I am not sure if this is the place to ask this type of question so please close this question if it is irrelevant.
I am learning about OO design and am having some issues creating a good design for a simple robot system. Here is the gist of it:
A driver operates a robot object. Robot is an interface which BasicRobot and HandicapRobot implement.
Here is the issue: BasicRobot has all of the code inside and HandicapRobot only differs by two variables. That is, BasicRobot has sensors in all directions whereas HandicapRobot only has left and forward sensor. Since they are so similar, I made HandicapRobot inherit from BasicRobot.
However, in some situations, I can only use BasicRobot and using HandicapRobot would not be appropriate. This violates a substitution rule since a subclass can be used whenever a parent class is expected.
I'm not sure how to solve this issue in an elegant way. Should I get rid of HandicapRobot and simply create sensor modifiers for BasicRobot?
A BasicRobot can be used wherever a HandicapRobot can be used, but a HandicapRobot cannot be used wherever a BasicRobot can be used. That implies that HandicapRobot should be the base class.
That said, there may be other problems with your hierarchy. If the two variables that are different are bools, then it is likely that you need to break out some code from your base class and put it in your derived class.
It looks like an application of decorator design pattern. You have to create an interface:
IRobot then have two classes implementing this interface BasicRobot and HandicapedRobot. HandicapedRobot will contain an instance of a BasicRobot through the IRobot.
interface IRobot{}
class BasicRobot : implements IRobot{}
class HandicapedRobot : implements IRobot{
IRobot m_internal;
SomeType m_additionalData;
}
Related
I am struggling to understand both abstract and interface approach. Since i get the idea what is the purpose to use one over another is clear. I was trying to found whatever example of using them both in action however all tutorials are how to use interface over abstract or vice versa showing usage either for one or another. I would really love to see practical example which could show both in action best on some real life example. Additional comments why in specific case you used one over another appreciated. Generics are very welcome to see as well in such example.
I'll propose foloowing example. We got some engine to get files from diffrent locations which could be taken using diffrent protocols as follows. I would like to understand on this example how this could be accomplished with both interfaces and abstract.
'As all of protocol has to close and open would it be good to put in abstract?
abstract class Collector
Protected Id
Protected Name
MustInherit Sub OpenConnection
MustInherit Sub CloseConection
End Class
'?
class Ftp : Collector
class Sftp: Collector
class Soap: Collector
'Interface?
Public Interface IRepository(Of T, Tkey)
Function GetAllFiles() As IEnumerable(Of T)
Function GetAllById(Tkey) as IEnumerable(Of T)
End Interface
Some key distinctions:
An abstract class can contain some implementation. An interface cannot.
In .NET, a class can not inherit from multiple base classes.
A class can implement multiple interfaces
The choice of which approach is really up to you. In general, it's a choice between the Composition pattern or Inheritance.
Composition uses Interfaces. Think of an object as having X.
Inheritance uses Classes. Think of an object as being X.
In either case, an abstract class or an interface is just a Type, through which you will access and manipulate them. For example, if you have some code that wants to perform Insert/Update/Delete operations, it doesn't need to know that the object it is operating on is a FTP client--only that the object has the ability to support these operations. (and that is exactly what IRepository specifies)
You definitely can combine both. There's no reason a concrete FtpClient class couldn't inherit from an abstract Protocol class and also implement the IRepository interface. It could even use generics!
Interfaces are great for decoupling your code, and also great for unit test mocks.
There is also a good summary of pros & cons on Wikipedia (Composition_over_inheritance). Pros:
To favor composition over inheritance is a design principle that gives the design higher flexibility. It is more natural to build business-domain classes out of various components than trying to find commonality between them and creating a family tree. For example, a gas pedal and a wheel share very few common traits, yet are both vital components in a car. What they can do and how they can be used to benefit the car is easily defined. Composition also provides a more stable business domain in the long term as it is less prone to the quirks of the family members. In other words, it is better to compose what an object can do (HAS-A) than extend what it is (IS-A).
Initial design is simplified by identifying system object behaviors in separate interfaces instead of creating a hierarchical relationship to distribute behaviors among business-domain classes via inheritance. This approach more easily accommodates future requirements changes that would otherwise require a complete restructuring of business-domain classes in the inheritance model. Additionally, it avoids problems often associated with relatively minor changes to an inheritance-based model that includes several generations of classes.
Cons:
One common drawback of using composition instead of inheritance is that methods being provided by individual components may have to be implemented in the derived type, even if they are only forwarding methods. In contrast, inheritance does not require all of the base class's methods to be re-implemented within the derived class. Rather, the derived class only needs to implement (override) the methods having different behavior than the base class methods. This can require significantly less programming effort if the base class contains many methods providing default behavior and only a few of them need to be overridden within the derived class.
I don't understand why you want to have an example combining both. Let's just say both are valid ways to build solid software architecture. They're just two tools - like having a kitchen knife and a meat cleaver. You won't necessarily use them together but see the pro's and con's when looking at the dinner you want to serve.
So usually you take abstract/MustInherit classes if you want to provide a common denominator. Sub-classes derive from the abstract one and have to implement the methods just like they would if they implemeted an interface. The good thing here is that abstract classes can provide "base logic" which can be developed centrally and all the sub-classes can make use of that. In the best case, abstract classes provide kind of "hooks" to plug in special logic in the sub-classes.
Interfaces describe what a class has to fulfill. So everything an interface defines has to be implemented in classes implementing the interface. There's no reusable logic built-in in this approach like in abstract base classes but the big "pro" for interfaces is that they don't take away the single base type you can derive from like abstract classes do. So you can derive from anything or nothing and still implement an interface. AND: You can implement multiple interfaces.
One word to the "reusable logic" with interfaces. While this is not really wroing, the .NET framework allows use to write extension methods on types (and interfaces) to attach externally developed code. This allows code reuse with interfaces like having a method implemented in there. So for example, you could write an extension method None() for the interface IEnumerable which is checking whether the enumerable is empty.
public static bool None(this IEnumerable values)
{
return !values.Any();
}
With this, None() can be used on any IEnumerable in your code base having access to the extension method (in fact, Any(), Select(), Where(), etc. are extension methods as well, lying in the System.Linq namespace).
Say I have an interface Interface and a concrete class ConcreteClass that implements Interface. Now consider a third class MyClass. If instances of MyClass hold a reference to ConcreteClass:
Interface ref = new ConcreteClass();
then should I associate MyClass with Interface or ConcreteClass in UML class diagram?
Thanks
That depends on what the public interface of MyClass defines.
If the public interface makes an Interface available, then you should link to that on the diagram. This would be the usual approach as the Interface is the general type and specifies the contract. Unless you have a reason to limit to ConcreteClass, don't.
If the public interface makes a ConcreteClass available, then you should link to that on the diagram.
The fact that at runtime a variable of type Interface actually holds an instance of ConcreteClass is beside the point. The diagram represents the relationships.
Solely with the Interface. The point is that you want the behavior of the interface. Whatever the implementation is of that interface is for the picture of no importance. MyClass has a relation with the interface, not with the implementation of the interface.
This principle is called Design By Interface. In the answer given by nakosspy is it his first picture. But it would even be better to leave the implementation of ConcreteClass out of the picture. The implementation is of no importance at that conceptual level. If there is a variable pointing to an interface, then is it obvious to the educated reader that there should be a concrete implementation as well.
If you would make a reference to the ConcreteClass then would you have to change the diagram everytime you change the implementation of the interface. That is not what you want. It is bad coding practice and bad uml practice.
It is good coding practice to separate the declaration of the relationship between MyClass and the Interface and the practical implementation of the Interface. By example:
Interface ref = new ConcreteClass();
should never happen in the class MyClass.
You should have something like this instead:
class MyClass
Interface ref;
setRef(){
ref = InterfaceImplementation();
}
}
This way can you change the implementation of Interface without changing one line of code in MyClass. Altough this might look much ado when you write one class, think of it when you are managing hundreds of classes.
So: it depends.
It's equally legal to associate MyClass with ConcreteClass or Interface. You won't find the answer to your question in the UML spec. Why? Because the answer lies in your problem domain, not the modelling language.
Consider two contrived examples to illustrate the point.
Example 1: Association between Classes
Substitute:
ICanBark for Interface
Dog for ConcreteClass
Trainer for MyClass
Let's assume the association we want to capture is Trains, i.e.
Each Trainer trains many Dogs
Each Dog is trained by at most one Trainer
In this case the association exists because of the 'Dogginess', not the 'Barkiness'. So it properly exists between the two classes.
Example 2: Association between Class and Interface
Substitute:
ILogger for Interface
FileLogger for ConcreteClass
Application for MyClass
In this case the relationship is about the 'Logginess', not the 'Fileness'. Application shouldn't care how the interface is implemented; it just wants a way to log messages. So the Association exists between the Class and the Interface
Summary
As is nearly always the case with Associations, the key to solving the problem lies in the problem domain itself - not the modelling language.
hth.
There are 2 ways to present the ref variable of MyClass: You can present it as attribute or as association. Then there are two alternative notations for the Interface interface: Square with the interface stereotype or circle. This makes 2*2=4 alternatives.
Show ref as association and use square interface notation.
Here you can't show the initial value that ref takes. That's because you can't show default values in associations.
Show ref as association but use the circle notation for the Interface.
As it was with the previous alternative, again here you can't show the initial value.
Show ref as attribute and use square interface notation.
Here you can show the default value, because you can do that for attributes. The relationship between MyClass and Interface is presented as a dependency. The same happens for the dependency between MyClass and ConcreteClass.
Note that this dependency (MyClass depends on ConcreteClass) can be presented also in the alternatives 1 and 2, you can add a dependency arrow (dashed) pointing from MyClass to ConcreteClass.
Show ref as attribute and use circle interface notation.
Again here you can show the default value.
If we count also the alternatives derived from presenting or not the dependencies, then there are at least 6 ways to present the same thing. Now the question is which to chose.
It depends on what do you want to visualize with the diagram and for whom the diagram is intended. In this case if the initialization of ref is the message, then you should use an alternative that presents it. If it's less important, then you might prefer a diagram that shows ref as association.
In a real problem you have more elements, so it makes much more alternatives. It's always up to you to decide what to present and how.
EDIT: Some references to help you understand the notation of interface implementation.
According to wikipedia:
A realization is a relationship between classes, interfaces,
components, and packages that connects a client element with a
supplier element. A realization relationship between classes and
interfaces and between components and interfaces shows that the class
realizes the operations offered by the interface.
You can find some quick reference examples and a lot of information at uml-diagrams.org.
This excellent answer Explanation of the UML arrows will help you with more examples.
Here you can also find some more info on realization.
You can define reference to concrete class as:
Attribute typed as Interface (or ConcreteClass) defined in MyClass, or
Association between MyClass and Interface (or ConcreteClass).
no more options are avialable
It's good practice for a class' implementation to be defined by interfaces. If a class has any public methods that aren't covered by any interfaces then they have the potential to leak their implementation.
E.g. if class Foo has methods bar() and baz() but only bar() is covered by an interface then any use of baz() doesn't use an interface.
It feels like to get cleaner code it would make sense to either:
create extra interfaces if the class has to have those methods (eg a separate interface to cover the behavior of baz() above)
or ideally refactor (eg using more composition) so the class doesn't need to have so many methods (put baz() in another class)
Having methods not covered by an interface feels like a code smell. Or am I being unrealistic?
I consider it as "overusing" the interface.
Interface can give you access only to limited functionality, therefore it is good for gathering more classes with similar functionality into one List<Interface> and using them, for example.
Or if you want to keep loose coupling principle, you rather give another component some interface than the whole class(es).
Also some classes should have restricted access to another classes, which can be done with interfaces too.
However high cohesion principle (which is usually connected to loose coupling) does not prevent you from using class itself, if two classes are and should be "strong" connected to each other.
I don't think that's the purpose of interfaces. If you actually talk about the 'is-a' and 'has-a' relationship between classes, not necessarily a class needs to cover all public methods in interfaces. That's like taking the concept too far.
A class can have methods which describe it's behavior but then, there are some methods that do not exactly describe the classes' behavior but rather describe what else the class can do.
In case if a question arises about SRP regarding the 'can-do' behaviors, it is possible that the class can use a component to execute those behaviors rather than implementing within itself.
For e.g., I have a class DataGrid, why would I need to have an interface called IDataGrid which exposes all the public methods. But may be there is an additional functionality that the DataGrid can do, which is export the data. In that case I can have it implement IExportData, and implement the ExportData method, which in turn does not export the data but uses a component, say DataExportHelper, that actually does the job.
The DataGrid only passes the data to the component.
I don't think SRP will be violated in the above example.
EDIT:
I am a .Net developer, so would like to give you and example from MS library classes. For e.g., the class System.Windows.Window does not implemnt any interface that has Close() method. And I don't see why it should be a part of any presenter.
Also, it is possible that something might look seem like a code smell but not necessarily it might be wrong. Code smell itself does not mean there is a problem but that there is a possibility of problem.
I have never come across any principle or guideline in software design which mentions that all the public members of a class need to be exposed in some or the other interface. May be doing that just for the sake of it might be a bad design.
No, I would definitely not consider methods not covered by an interface a code smell.
It seems like this might be dependent on the object infrastructure you are building in, but in the infrastructures I'm familiar with, the real point of interfaces is to provide a manageable form of multiple inheritance. I consider the overuse of multiple inheritance a notable smell.
In .NET at least, abstract classes are explicitly the preferred construct for exposing abstraction (not interfaces). The .NET design guidelines say: Do favor defining classes over interfaces., with rationale described here http://msdn.microsoft.com/en-us/library/vstudio/ms229013(v=vs.100).aspx.
Even in COM (where any externally visible functionality had to be defined in an interface) there are perfectly good reasons to have non-exposed functions: limiting the visibility of implementation details. COM was originally defined in C (not C++) which lacked the richer set of access modifiers that newer languages have, but the concepts were there: published interface members were public, everything else was internal.
While certain guidelines state that you should use an interface when you want to define a contract for a class where inheritance is not clear (IDomesticated) and inheritance when the class is an extension of another (Cat : Mammal, Snake : Reptile), there are cases when (in my opinion) these guidelines enter a gray area.
For example, say my implementation was Cat : Pet. Pet is an abstract class. Should that be expanded to Cat : Mammal, IDomesticated where Mammal is an abstract class and IDomesticated is an interface? Or am I in conflict with the KISS/YAGNI principles (even though I'm not sure whether there will be a Wolf class in the future, which would not be able to inherit from Pet)?
Moving away from the metaphorical Cats and Pets, let's say I have some classes that represent sources for incoming data. They all need to implement the same base somehow. I could implement some generic code in an abstract Source class and inherit from it. I could also just make an ISource interface (which feels more "right" to me) and re-implement the generic code in each class (which is less intuitive). Finally, I could "have the cake and eat it" by making both the abstract class and the interface. What's best?
These two cases bring up points for using only an abstract class, only an interface and using both an abstract class and an interface. Are these all valid choices, or are there "rules" for when one should be used over another?
I'd like to clarify that by "using both an abstract class and an interface" that includes the case when they essentially represent the same thing (Source and ISource both have the same members), but the class adds generic functionality while the interface specifies the contract.
Also worth noting is that this question is mostly for languages that do not support multiple inheritance (such as .NET and Java).
As a first rule of thumb, I prefer abstract classes over interfaces, based on the .NET Design Guidelines. The reasoning applies much wider than .NET, but is better explained in the book Framework Design Guidelines.
The main reasoning behind the preference for abstract base classes is versioning, because you can always add a new virtual member to an abstract base class without breaking existing clients. That's not possible with interfaces.
There are scenarios where an interface is still the correct choice (particularly when you don't care about versioning), but being aware of the advantages and disadvantages enables you to make the correct decision.
So as a partial answer before I continue: Having both an interface and a base class only makes sense if you decide to code against an interface in the first place. If you allow an interface, you must code against that interface only, since otherwise you would be violating the Liskov Substitution Principle. In other words, even if you provide a base class that implements the interface, you cannot let your code consume that base class.
If you decide to code against a base class, having an interface makes no sense.
If you decide to code against an interface, having a base class that provides default functionality is optional. It is not necessary, but may speed up things for implementers, so you can provide one as a courtesy.
An example that springs to mind is in ASP.NET MVC. The request pipeline works on IController, but there's a Controller base class that you typically use to implement behavior.
Final answer: If using an abstract base class, use only that. If using an interface, a base class is an optional courtesy to implementers.
Update: I no longer prefer abstract classes over interfaces, and I haven't for a long time; instead, I favour composition over inheritance, using SOLID as a guideline.
(While I could edit the above text directly, it would radically change the nature of the post, and since a few people have found it valuable enough to up-vote it, I'd rather let the original text stand, and instead add this note. The latter part of the post is still meaningful, so it would be a shame to delete it, too.)
I tend to use base classes (abstract or not) to describe what something is, while I use interfaces to describe the capabilities of an object.
A Cat is a Mammal but one of it's capabilities is that it is Pettable.
Or, to put it a different way, classes are nouns, while interfaces map closer to adjectives.
From MSDN, Recommendations for Abstract Classes vs. Interfaces
If you anticipate creating multiple versions of your component, create an abstract class. Abstract classes provide a simple and easy way to version your components. By updating the base class, all inheriting classes are automatically updated with the change. Interfaces, on the other hand, cannot be changed once created. If a new version of an interface is required, you must create a whole new interface.
If the functionality you are creating will be useful across a wide range of disparate objects, use an interface. Abstract classes should be used primarily for objects that are closely related, whereas interfaces are best suited for providing common functionality to unrelated classes.
If you are designing small, concise bits of functionality, use interfaces. If you are designing large functional units, use an abstract class.
If you want to provide common, implemented functionality among all implementations of your component, use an abstract class. Abstract classes allow you to partially implement your class, whereas interfaces contain no implementation for any members.
If you want to provide the option of replacing your implementation completely, use an interface. This applies especially for interactions between major components, these should always be decoupled by interfaces.
There may also be technical reasons for prefering an interface, for example to enable mocking in unit tests.
Internally in a component it may be fine to just use an abstract class directly to access a hierarchy of classes.
If you use an interface and have a hierarchy of implementing classes then it is good practice to have an abstract classe which contain the common parts of the implementation. E.g.
interface Foo
abstract class FooBase implements Foo
class FunnyFoo extends FooBase
class SeriousFoo extends FooBase
You could also have more abstract classes inheriting from each other for a more complicated hierarchy.
Refer to below SE question for generic guidelines:
Interface vs Abstract Class (general OO)
Practical use case for interface:
Implementation of Strategy_pattern: Define your strategy as an interface. Switch the implementation dynamically with one of concrete implementations of strategy at run time.
Define a capability among multiple unrelated classes.
Practical use case for abstract class:
Implementation of Template_method_pattern: Define a skeleton of an algorithm. The child classes can't change strucutre of the algortihm but they can re-define a part of the implementation in child classes.
When you want share non-static and non-final variables among multiple related classes with "has a" relation.
Use of both abstradt class and interface:
If you are going for an abstract class, you can move abstract methods to interface and abstract class can simply implement that interface. All use cases of abstract classes can fall into this category.
I always use these guidelines:
Use interfaces for multiple TYPE inheritance (as .NET/Java don't use multiple inheritance)
Use abstract classes for a re-usable implementation of a type
The rule of the dominant concern dictates that a class always has a main concern and 0 or more others (see http://citeseer.ist.psu.edu/tarr99degrees.html). Those 0 or more others you then implement through interfaces, as the class then implements all the types it has to implement (its own, and all interfaces it implements).
In a world of multiple implementation inheritance (e.g. C++/Eiffel), one would inherit from classes which implement the interfaces. (In theory. In practise it might not work that well.)
There is also something called the DRY principle - Don't Repeat Yourself.
In your example of data sources you say there is some generic code that is common between different implementations. To me it seems that the best way to handle that would be to have an abstract class with the generic code in it and some concrete classes extending it.
The advantage is that every bug fix in generic code benefits all concrete implementations.
If you go interface only you will have to maintain several copies of the same code which is asking for trouble.
Regarding abstract + interface if there is no immediate justification for it I would not do it. Extracting interface from abstract class is an easy refactoring, so I would do it only when it is actually needed.
I have a few questions for you wise people involving OO design with Interfaces and abstract base classes. Consider the following scenario:
I have an abstract bass class "DataObjectBase" and a derived class "UserDataObject." I also have an interface "IDataObject." The interface of course exposes all of the public methods and properties that my Data Objects must expose, and you can probably guess that the abstract base implements the methods and properties common to all Data Objects.
My question is, if the abstract bass class DataObjectBase implements everything specified in the interface IDataObject, should the interface be declared on the base class, or on the derived classes(s)?
In C# interfaces declared on the base class are implicity applied to the derived classes, but is this the best practice? It seems to me that implementing the interface on the base class makes it less obvious that the derived class implements the interface, but then again requires the Interface to be specified for each derived class.
Additionally, if the base class was NOT abstract, would the reccomendation change?
A second sub-question: If the base class implements all of the methods/properties of the IDataObject interface, is the interface even needed? The base class typename can simply be used in place of the interface name, ie:
private DataObjectBase _dataObject;
private IDataObject _dataObject;
In the above example (where again the base implements everything exposed by the interface) both can be assigned the same derived types. Personally I always use the interface in these situations, but I am intrested in hearing peoples thoughts.
Thanks in advance.
My way of thinking about such problems is to consider the different people reading the code, the "roles" if you like. Also consider the overall maintainability of the system.
First there is some code expecting to use the Interface. It's written in terms of the interface, the author has (should have) no interest in the implementation. That's why we provide the Interface class. From that perspective the Abstract Base Class is just one of many possible implementation hierarchies. Don't tell this role about implementation details. Keep the Interface.
Then we have the role who is designing an implementation. They come up with one possible approach and discover some variations, so they want to pull common code together. Abstract Base Class - fill in the common stuff here, let detailed implementers fill in the gaps. Help them by providing abstract methods saying "your code goes here". Note that these methods need not only be the ones in the Interface. Also note that this Abstract Base Class might even implement more that one Interface! (eg. It's CleverThingWorker but also a IntermediateWorkPersister.)
Then we have the role who actually do the fine detailed implementation. Fill in the gaps here. Dead easy to understand. In this case you don't even need to consider the Interface as such. Your job is to make that abstract class concrete.
Bottom line ... I use both Interfaces and Base classes. You put the Interface on the Base Class. We don't add value by adding it to the implementation class.
If your user classes will always inherit from one base class, then you don't need the interface. If there is a possibility that you will have classes that match the interface but are not derived from the base class, then use the interface.
As for the interface being hidden in the base class and hence not immediately visible in the user class, this is normal and can be dealt withg by the compiler. This is also where good naming conventions come in - your UserDataObject has a name that matches IDataObject, as does DataObjectBase. You could add a comment to the class file that says it inherits from IDataObject, but it will be visible that it inherits from DataObjectBase, which in turn looks like it inherits from IDataObject by its name.
The other thing that needs to be mentioned is that the use of interfaces makes it easier to implement automated tests.
Say, for example, that one of the methods of the interface is supposed to throw a exception - such as 'DatabaseConnectionLostException' - and you want to test client code to check that it behaves correctly in such a situation.
It is a simple matter to provide an implementation of the interface that throws the exception, allowing the test to be written.
If you used the abstract base class instead of the interface, this operation would be quite a bit trickier (OK, you can use Mocks, but the interface solution is much cleaner)