I want to model a file system which contains both files and directories, and directories can contain either files or other directories.This is what I have reached so far:In, however, a similar model is presented:Now I have two questions:.I wonder why the author did not use an Interface to represent the abstract type FileSystemElement? Isn't using an interface for this type correct?.As we know, files and directories must have names with similar constraint (e.g. Maximum length of 256 characters).
![]()
Root/umlClass/class?version=4&author=Cinergix Mailbox + name: string + refresh( ): boolean + deleteAllMessages( ): boolean + countAllMessages ( ): integer.
Therefore, it would be nice if I model this in the FileSystemElement. But an interface cannot have a abstract attribute, so I have to repeat name attribute in both Directory and File classes. Is there any better workaround for this problem?
![]()
Regarding your first question: If Directory and File were supposed to be the only possible subtypes of FileSystemElement, you could not enforce that constraint with an interface as the supertype; anyone is allowed to implement an interface they have access to. You would instead need an abstract class with a constructor that has package visibility ( in UML). So if your package cannot actually deal with any kind of FileSystemElement, but expects only the subtypes that you defined yourself, you'd need an abstract base class.–Nov 29 '14 at 9:29.
Isn't using an interface for this type correct?Using an interface in this case would work, but you would have to duplicate behavior between Directory and File (like having a maximum of 256 chars for the name). You would be better off making FileSystemElement an abstract class (assuming your language of choice supports it) Which also answers your second question: an abstract class can provide default behavior for its children. You can just declare the Name property inside the parent class, with the associated validations, etc. That way, Directory and File will inherit the property and the behavior.
You won't have to redefine anything in the Directory of File class. No code duplication. The base class approach makes sense because of the problem you raised in your second question. A base class allows you to have such an attribute and don't repeat yourself on validity checks etc.On the other hand your interface approach makes sense because it offers you more flexibility. Suppose you want to add a third type of FileSystemElement that does not have a name attribute. And maybe this third type lends itself to use a very different base class.
But you still want to address all three types from the Directory class. You can't do that with a base class.So, let's see if we can combine the features. The motto here is separation of concerns. concern: address all elements of a filesystem in the same way.
concern: Share the name implementation between the Directory and the File class.We can't do both with one technique but nothing stops us from using both at the same time! Let's make FileSystemElement an interface and let Directory and File implement it. Additionally create a base class (possibly an abstract one) called e.g. NamedFileSystemElement with the desired attribute. Now let Directory and File inherit from NamedFileSystemElement.
See, best of both worlds. @marcof Maybe I should have made it more clearly that my answer is more concerned with a general composite pattern and the filesystem is just an example. I cannot think of any third FileSystemElement descendant either. But if you are designing classes for filesystems they are pretty likely to end up in a library and then you really want to separate your implementation from your interface. You cannot do that after releasing the lib. You find this approach often in real libs e.g. AbstractTableModel in Swing.
If the OP is only about a non-lib filesystem model, go ahead, cut out the interface.–Apr 28 '12 at 8:25.
![]() Comments are closed.
|
AuthorWrite something about yourself. No need to be fancy, just an overview. Archives
February 2023
Categories |