Related
I know this question's been asked before (e.g., What is the difference between the bridge pattern and the strategy pattern?).
However, could someone please explain, using clear-cut examples, what the difference is and in what sorts of cases one must be selected over the other? Less conceptual theory, more practical "real-life" scenarios would be appreciated.
The Bridge Pattern makes a distinction between an abstraction and an implementation in such a way that the two can vary independently. I will use the example from
Patterns in Java, Volume 1: A Catalog of Reusable Design Patterns Illustrated with UML, Second Edition
You need to provide classes that access physical sensors such as found in scales, speed measuring devices etc. Each sensor produces a number but the number could mean different things. For the scale it could mean the weight and for the speed measuring device it may mean speed.
So you can start by creating a Sensor abstract class to represent the commonality between all sensors and various subclasses for the different types of sensors. This is a robust design allowing you to provide many more types of sensors in the future.
Now suppose that sensors are provided by different manufacturers. You will have to create a heirarchy of sensor classes for manufacturer X and another for manufacturer Y. The problem now is that the clients would need to know the difference between the manufacturers. And if you decide to support a third manufacturer...?
The solution is to provide the main abstraction heirarchy, ie. the Sensor abstract class and sub classes such as SpeedSensor and WeightSensor and so on. Then provide the interface (Bridge) that will exist between the abstraction and the implementation. So there will be a SensorInterface, WeightSensorInterface and SpeedSensorInterface, which dictates the interface that each concrete sensor class must provide. The abstraction does not know about the implementation, rather it knows about the interface. Finally, you can create an concreate implementation for each manufacturer. That is, XSensor, XWeightSensor and XSpeedSensor, YSensor, YSpeedSensor and YWeightSensor.
Clients depend only on the abstraction but any implementation could be plugged in. So in this setup, the abstraction could be changed without changing any of the concrete classes, and the implementation could be changed without worrying about the abstraction.
As you can see this describes a way to structure your classes.
The Strategy on the other hand is concerned with changing the behaviour of an object at run time. I like to use the example of a game with a character that possesses several different types of weapons. The character can attack but the behaviour of attack depends on the weapon that the character is holding at the time, and this cannot be known at compile time.
So you make the weapon behaviour pluggable and inject it into the character as needed. Hence a behavioral pattern.
These two patterns solve different problems. The strategy is concerned with making algorithms interchangeable while the Bridge is concerned with decoupling the abstraction from the inplementation so that you can provide multiple implementations for the same abstraction. That is, the bridge is concerned with entire structures.
Here are a few links that might be useful:
Bridge Pattern
Strategy Pattern
I can tell this is hard to explain. Many people who use it and understand it have a hard time explaining it to newbies.
For those like me who think in terms of analogies:
Strategy Pattern
So strategy is kind-of a one-dimensional concept. Think of a one-dimensional array of strategies to choose from.
Example 1: Plumber's tools
The strategy pattern is like a plumber who has various tools to get a pipe unclogged. The job is the same each time; it's to unclog the pipe. But the tool he chooses to get this done can vary depending on the situation. Maybe he'll try one and if that doesn't work he'll try another.
In this analogy, "unclog the pipe" is the method that will implement one of the strategies. Snake brush, power auger, and draino are the concrete strategies, and the plumber is the class containing the method (labeled "Context" in most diagrams).
Example 2: Multi-bit screwdriver
Or you could think of the interchangeable bits on a multi-bit screwdriver.
They are meant to be changed out at run-time to suit the job at hand, which is to screw something.
Bridge Pattern
So bridge is a two-dimensional concept. Think of one dimension (the rows) being the list of methods that need to be implemented, and the second dimension (the columns) being the Implementors who will implement each one of those methods.
Example 1: Apps and devices
The bridge pattern is like a person that has many ways that they can communicate (email, text, google voice, phone, skype) and many devices on with which they can communicate in these various ways - a PC, a tablet, and a smart phone.
The various ways to communicate (email, text, phone) would be the methods on an abstract interface, let's call it "CommunicationDevice". In this pattern, CommunicationDevice is the Implementor. Each device in this analogy (PC, tablet, smart phone) is the ConcreteImplementor that implements all these methods (email, text, phone).
Example 2: Odbc database drivers and odbc functions
Another ready example of bridge is the odbc or oledb database driver modules from Windows. They all implement the various methods on the same standard "database driver" interface, but they implement that interface in different ways. Even if you are using the same database, say Sql Server, there are still different drivers that can talk to Sql Server, albeit in different ways under the covers.
Example 3: Implementors (columns) implementing methods (rows)
Strategy pattern
This pattern lets the algorithm that executes vary independently from the clients that use it. i.e. Instead of having a fixed algorithm to exeucte for a given sitaution, it allows one among many algorithms to be selected on-the-fly at runtime. This involves removing an algorithm from its host class and putting it in a separate class.
For example, suppose one wants to travel from a city to another, then he has several choices: take a bus, hire a car, catch a train, etc. So each mode of transport selected would transpire into a separate algorithm to be executed. The mode of transport chosen will depend on various factors decided at runtime (cost, time, etc.). In other words, the strategy chosen to execute will be decided on-the-fly.
Another example, suppose one wants to implement a SortedList class(main controller) that Sorts based on a strategy. The strategy is the method that one uses to sort (like MergeSort, QuickSort).
Comparison with the Bridge pattern
The main difference (even though both patterns have the same UML) is that unlike the bridge pattern (which is a structural pattern), the strategy pattern is a behavioral pattern. Structural patterns suggest ways in which objects are composed or associated or inherited to forms larger objects i.e. they focus on object composition. While behavioral patterns deal with the algorithm or business logic (and not on the object creation itself) i.e. they focus on the collaboration between objects.
Note that most algorithms can be implementated as static or singleton classes required only single instance creation (i.e. new is not called for everytime a strategy is set).
A closer look at the implementation of the two patterns will reveal that in the bridge pattern one creates the concrete implementation of the object and then the call.
// Set implementation and call
// i.e. Returns (creates) the concrete implementation of the object,
// subsequently operation is called on the concrete implementation
ab.Implementor = new ConcreteImplementorA();
ab.Operation();
Whereas in the case of the strategy pattern, one will not use the concrete implementation of the algorithm directly, instead he will create the context in which the strategy should execute,
// Set the context with a strategy
// i.e. Sets the concrete strategy into the context, concrete implementation of the class not
// directly available as a data object (only the algorithm is available).
context = new Context (new ConcreteStrategyA());
context.contextInterface();
// Strategy can be reused instead of creating a new instance every time it is used.
// Sort example
MergeSort mergeSort = new MergeSort();
QuickSort quickSort = new QuickSort();
...
context = new Context (mergeSort);
context.Sort();
...
context = new Context (quickSort);
context.Sort();
...
context = new Context (mergeSort);
context.Sort();
The Bridge pattern tells how organize classes, the Strategy - how organize algorithms.
Difference between bridge and strategy pattern:
Bridge pattern gives us the ability to re implement, being running business structure as per our current situation , other side strategy pattern gives us ability to implement our various business strategy and encapsulate them and use them as per situation or at a time.
Main difference between both is using bridge pattern we can change our whole structure but using strategy we are able to change our business strategy parallelly.
I have elaborated two very important design patter below as per my understanding.
please carefully go throw this i think it will clear your understanding about both them.
Bridge Pattern:
What is Bridge Design Pattern?
The sense of GoF suggested Bridge pattern is decouple the implementation of an component from it's abstraction.
When we will use the Bridge Design Pattern?
Let imagine a situation where a component already implemented, and it's running well as per your business need. Suddenly the organisation changed their business strategy. For this you need to be change or re-implemented the component. At this situation, what you will do change the previous one that are running well last few years, or you Create the new component. At this situation bridge pattern beautifully handled the scenario. See the example below for better understanding.
// Main component
public interface Ibridge
{
void function1();
}
// Already Implemented that are currently being using
public class Bridge1 : Ibridge
{
public void function1()
{
Console.WriteLine("Implemented function from bridge 1");
}
}
//New Implementation as per Organisation needs
public class Bridge2 : Ibridge
{
public void function1()
{
Console.WriteLine("Implemented function from bridge2");
}
}
//Abstract Calling functionalities
public interface IAbstractBridge
{
void CallFunc1();
}
// implementation of calling implemented component at a time
public class AbstractBridge:IAbstractBridge
{
protected Ibridge _ibridge;
public Ibridge Ibridge
{
set { _ibridge = value; }
}
public void CallFunc1()
{
this._ibridge.function1();
}
}
class Program
{
static void Main(string[] args)
{
AbstractBridge abp = new AbstractBridge();
/*
here you see that now being using the previous implemented component.
but need change newly implemented component so here we need just changed
the implementation of component, please see below
*/
//Commented old one
abp.Ibridge = new Bridge1();
//using new one just change the "Bridge1" to "Bridge2"
abp.Ibridge = new Bridge2();
abp.CallFunc1();
}
}
Strategy design Pattern:
What is Strategy Design Pattern?
The sense of GoF suggested Strategy pattern is Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
When we will use the Strategy Design Pattern?
Let imagine a situation where a owner of shopping complex want to attract customer giving different discount offer based on their various occasion and the discount offer any time owner can switch from discount mode to normal mode vice versa ,then how to handle this situation At this situation strategy pattern handled the scenario. Lets See the example below for better understanding.
All Strategy:
public interface ISellingStrategy
{
void selling();
}
public class BasicStrategy : ISellingStrategy
{
public void selling()
{
Console.WriteLine("Buy Three get 5% discount.");
}
}
public class ChrismasStrategy : ISellingStrategy
{
public void selling()
{
Console.WriteLine("Buy Three get one offer + extra 5% discount.");
}
}
public class HoliFestiveStrategy : ISellingStrategy
{
public void selling()
{
Console.WriteLine("Buy two get one offer + extra 5% discount.");
}
}
public class DurgapuljaStrategy : ISellingStrategy
{
public void selling()
{
Console.WriteLine("Buy one get one offer + extra 5% discount.");
}
}
Billing:
public class Billing
{
private ISellingStrategy strategy;
public void SetStrategy(ISellingStrategy _strategy)
{
this.strategy = _strategy;
}
public void ApplyStrategy()
{
strategy.selling();
Console.WriteLine("Please wait offer is being applying...");
Console.WriteLine("Offer is now Applied and ready for billing..");
}
}
Factory patter for Creating Object of Billing Class
public class BillingFactory
{
public static Billing CreateBillingObject()
{
return new Billing();
}
}
Calling
class Program
{
static void Main(string[] args)
{
Billing billing = BillingFactory.CreateBillingObject();
billing.SetStrategy(new BasicStrategy());
billing.ApplyStrategy();
Console.ReadLine();
}
}
Both patterns separate interface from implementation. I think the key distinction is that the Bridge Pattern uses inheritance ("is a") while the Strategy Pattern uses composition ("has a").
Bridge Pattern:
class Sorter abstract
{
virtual void Sort() = 0;
}
// MergeSorter IS A Sorter
class MergeSorter : public Sorter
{
virtual void Sort() override;
}
Strategy Pattern:
class SortStrategy abstract
{
virtual void Sort() = 0;
}
// Sorter HAS A SortStrategy
class Sorter
{
Sorter(SortStragety *strategy) : mStrat(strategy) {}
void Sort() {mStrat->Sort();}
SortStrategy *mStrat;
}
The Strategy pattern encapsulates algorithms so that they can be used and changed in a complex program (without gumming up the works) and the Bridge pattern allows two interfaces loosely bound so that they can interact but be changed independently of one another.
You can find PHP examples of the Bridge and Strategy patterns here:
http://www.php5dp.com/category/design-patterns/bridge/
and
http://www.php5dp.com/category/design-patterns/strategy/
You'll find a lot of examples for both patterns that may be helpful.
Strategy:
Strategy is behavioral design pattern. If is used to switch between family of algorithms.
This pattern contains one abstract strategy interface and many concrete strategy implementations (algorithms) of that interface.
The application uses strategy interface only. Depending in some configuration parameter, the concrete strategy will be tagged to interface.
Bridge:
It allows both abstractions and implementations to vary independently.
It uses composition over inheritance.
Bridge is a structural pattern.
However, could someone please explain, using clear-cut examples, what the difference is and in what sorts of cases one must be selected over the other?
Refer to below post to get insight on use cases of Strategy and Bridge patterns:
Real World Example of the Strategy Pattern
When do you use the Bridge Pattern? How is it different from Adapter pattern?
On quick note:
Use Strategy pattern to dynamically change the implementation by replacing one strategy with other strategy.
One real word example : Airlines offering discounts during off-peak months. Simply change fare discount strategy with no-discount strategy during high peak time.
Use Bridge pattern when Abstractions and implementations have not been decided at compile time and can vary independently
One real world example in Automobile industry : Different type of Gears can be assembled into different types of Cars. Both Car and Gear specification and implementation can change independently.
Let me recite the answers from the linked question.
The bridge pattern is a structural pattern, that is, it lays out ideas of how to build a component of your project. It is used to hide two levels of abstractions. The sample code on Wikipedia (http://en.wikipedia.org/wiki/Bridge_pattern) explains it in most unambiguous terms.
The strategy pattern is a dynamic pattern. When any wild function can implement the requirements, a strategy pattern is used. Examples can be any program that allows for plugins to be developed and installed. On the Wikipedia pageg(http://en.wikipedia.org/wiki/Strategy_pattern), ConcreteStrategyAdd, ConcreteStrategySubtract, etc is plugin used in the ConcreteStrategy class. Any method could be used there that implements the interface Strategy.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
When to use an interface instead of an abstract class and vice versa?
Hi, I am teaching OOP concepts to non-programmers. I wanted to know how can you explain the difference between an interface and an abstract class.
What I am actually looking for, is a real world example that can help highlight the difference between the two.
The player Interface
In my Java courses I often use this kind of image and ask: "What is this ?"
Every time someone will say "that's a player". From this image you can teach anybody what an interface is. This Interface allow any user to "play" something. Everybody knows what these buttons mean, even if you don't know what exactly will be done, you can use anything with this interface and you know that the little arrow will "play" and other arrows will probably send you forward or backward.
Everything that will have those buttons will provide a standard behavior that any user will know before even starting to use them.
I usually try to avoid the "contract" word which can be misunderstood.
The DVD player Abstract class
And then from the Play Interface, I go to the VCR (or DVD) player. Every constructor of DVD player must add some special functions to transform a simple unknown player into a DVD player. For example the eject button. And they must correctly implement Player.
The play button will launch the content of the DVD.
But even if DVD Player provide the basic behavior of a DVD player, not everything is done. You can't simply have "a" DVD player, it has a brand and most of the time it has its own firmware. A this time you'll need to extend the DVD Player abstract class to add your own little components.
Here's a good comparison of the two: interface vs abstract class. I've copied a specific example from there below:
Interface
Interfaces are often used to describe the peripheral abilities of a class, not its central identity, e.g. An Automobile class might implement the Recyclable interface, which could apply to many otherwise totally unrelated objects.
Abstract class
An abstract class defines the core identity of its descendants. If you defined a Dog abstract class then Dalmatian descendants are Dogs, they are not merely dogable. Implemented interfaces enumerate the general things a class can do, not the things a class is.
Interface
An interface is simply a specification. It describes what something MUST do. Nothing more, nothing less. On its own, it is meaningless. It is only useful when someone takes that specification and implements it.
Think of a USB memory stick. It conforms to the specifications of USB. A device communicating with it doesn't need to know or care how the memory stick is going about its job, all it needs to know is that when we ask for data to be written, it is written; conversely, when we ask to read data from it we expect to receive the data.
In computing terms, we use an interface in the same way. If we have:
public interface IUSB
{
Data Read();
bool Write(Data data);
}
We know that anything implementing this interface has to provide an implementation for Read and Write. How or what it does behind the scenes is of no concern to us. By passing an interface around our code we're not tying ourselves down to specific implementations.
Abstract Class
An Abstract Class simply provides us with a means to put in place specification in a base class that derived types must implement, as well as common code that can be used by all derived types.
I've been trying to thing of a good real-world example and have struggled, so can only really come up with a code example.
Say you wanted to implement an employee hierarchy in your code. So you may have:
public abstract class Employee
{
public string FirstName { get; protected set; }
public string LastName { get; protected set; }
public string Grade { get; protected set; }
public int Salary { get; protected set; }
public abstract void GivePayRise();
}
Every employee has a name and an associated job grade. We can model this in the base class with the first 3 properties. However, giving a bonus may not be a straightforward affair, depending on grade etc. So, we mark this as abstract. Every derived type of Employee (Part-Time, Full-Time, Contract, Consultant) has to implement this.
An implementation may be:
public class FullTimeEmployee : Employee
{
public void GivePayRise()
{
Salary *= 1.1;
}
}
public class PartTimeEmployee : Employee
{
public void GivePayRise()
{
Salary *= 1;
}
}
So we want to give a 10% raise to full-time employees, but nothing to part-time ones.
Difficult to give good examples - I generally tend to use interfaces, can't really remember in the past year or so when I've used an abstract class. This could start the whole Abstract Class vs Interface debate, but that's a whole new page.......
For everything computer related, I use a cooking dinner example. I start by saying that hard drives are cabinets/storage closets. Memory is like your counter. Processor is the cooking apparatus (stove). You are like the system bus (moving things around, etc...). So when you boot a computer, you take your basic ingredients out of storage and put them on the counter (loading the OS). This is a loose example, but it works well.
Now to move into OOP: an ingredient is an object, so is a tool (bowl, knife, spoon, etc...). Each one of these has properties (knife= handle_color: black, blade_type: serrated, etc...). And each one has methods/actions that you can perform with them (knife = cut(pepper)).
Now you can take this as far as you want to. For instance, there are green, yellow and red peppers. Each one is a pepper, so you can say "inherit the pepper class" (layman: take everything you know about a pepper and apply it to this specific pepper, pepper has a color attribute, a red pepper is color=red).
You can even separate class from instance (this particular pepper is an instance, whereas on the recipe card it's a class).
So you could make some pseudocode:
class pepper {
var color
var spiciness
var size
}
class redPepper extends pepper {
construct(){
$this->color=red
}
}
class cuttingKnife extends knife{
construct(){
$this->blade_type=serated
}
}
class cookingPot extends pot{
construct(){
//We all know what a cooking pot is
}
}
class stove extends apparatus{
construct(){
//We all know what a stove is
}
}
$knife = new cuttingKnife();
$myPepper = new redPepper();
$pot = new cookingPot();
$stove = new stove();
$knife->cut($myPepper);
$pot->putOn($stove);
$stove->cookOn("high");
$pot->putIn("water");
$pot->putIn($myPepper);
//This will boil a cut pepper
Of course, people won't necessarily understand the pseudocode, but they would understand how to boil something. They would understand the difference between a "pepper" and a "red pepper". I think you can pretty much use this analogy for any computer related thing with some minor tweeks.
multithreading: add more burners to the stove and another cook in a single kitchen
multicore arch.: add a second kitchen
downloading/installing software: go to store, find food, bring home, deposit in storage
partitioning a HDD: different cabinets/fridge could be Linux proc system (because it's special).
Etc...
Interface: The buttons of the remote control. Users know how these buttons are supposed to function.
Concrete class: Toshiba RC, Philips RC, JVC RC - what's inside the box is the concrete implementation.
Abstract class: The stencil a tailor uses in order to create a Made to measure garment. While You can't wear the stencil itself it is used to produce suits You can wear - the suits are "derived" from the stencil.
Interface: A dress code.
A good example is a calculator. Inside a calculator is a circuit board that has connections between its display, buttons, and a logic processor.
The circuit board acts like an abstract class. It provides the plumbing for any calculator built with it. In addition, it has certain interfaces that connect to a display, to an array of buttons, and to a logic processor.
In turn, any display manufactured to work with the circuit board must have a connector that fits the display interface on the circuit board. The same goes for the buttons and the logic processor, the latter likely having a certain arrangement of pins that align with the interface on the circuit board.
A developer using OOD would create an abstract class, CalculatorBase, to define the plumbing between the buttons, the display, and the internal logic. The abstract class would also specify how derivative classes use this plumbing to respond to certain events.
CalculatorBase, however, wouldn't depend on a specific display, a specific set of buttons, or even a specific implementation of logic. Instead, the developer specifies an interface for each, such as ICalculatorDisplay, for example. ICalculatorDisplay would specify how CalculatorBase expects to interact with a display. CalculatorBase would then work with any display that implements ICalculatorDisplay.
(In some languages, abstract class is used the same way as an interface, so it may be confusing)
A handful of classes that all have a certain common interface is like a handful of words that can fill in the the blank in a sentence. Example:
____ has wings
Chicken has wings
Airbus A320 has wings
However, the classes themselves, while they can all fit the blank in the sentence, do not have any relatioship in between. Chicken is a fowl while Airbus A320 is an aircraft. The only commonality is that they both have something that we call "wings". (You can also say that the true meanings of the "wings" are different in the two situations.)
class IHasWings : public IUnknown
{
public:
// IUnknown methods: (Inherited)
// IHasWings methods:
virtual HRESULT GetWingSpan([out] double* pdblWingSpan) = 0;
virtual HRESULT IsWingMovable([out] BOOL* pIsMovable) = 0;
virtual HRESULT IsWingDetachable([out] BOOL* pIsDetachable) = 0;
};
class Chicken : public ... ..., public IHasWings
{
};
class AirbusA320 : public ... ..., public IHasWings
{
};
Very simply put, an interface defines how you can talk to me.
Whereas an abstract class could define one of my talents such as playing the guitar. The problem is that "playing guitar," by itself isn't really that useful. But we could use this ability to create a type of person, such as a musician (which we could say is a class).
Can anyone think of any situation to use multiple inheritance? Every case I can think of can be solved by the method operator
AnotherClass() { return this->something.anotherClass; }
Most uses of full scale Multiple inheritance are for mixins. As an example:
class DraggableWindow : Window, Draggable { }
class SkinnableWindow : Window, Skinnable { }
class DraggableSkinnableWindow : Window, Draggable, Skinnable { }
etc...
In most cases, it's best to use multiple inheritance to do strictly interface inheritance.
class DraggableWindow : Window, IDraggable { }
Then you implement the IDraggable interface in your DraggableWindow class. It's WAY too hard to write good mixin classes.
The benefit of the MI approach (even if you are only using Interface MI) is that you can then treat all kinds of different Windows as Window objects, but have the flexibility to create things that would not be possible (or more difficult) with single inheritance.
For example, in many class frameworks you see something like this:
class Control { }
class Window : Control { }
class Textbox : Control { }
Now, suppose you wanted a Textbox with Window characteristics? Like being dragable, having a titlebar, etc... You could do something like this:
class WindowedTextbox : Control, IWindow, ITexbox { }
In the single inheritance model, you can't easily inherit from both Window and Textbox without having some problems with duplicate Control objects and other kinds of problems. You can also treat a WindowedTextbox as a Window, a Textbox, or a Control.
Also, to address your .anotherClass() idiom, .anotherClass() returns a different object, while multiple inheritance allows the same object to be used for different purposes.
I find multiple inheritance particularly useful when using mixin classes.
As stated in Wikipedia:
In object-oriented programming
languages, a mixin is a class that
provides a certain functionality to be
inherited by a subclass, but is not
meant to stand alone.
An example of how our product uses mixin classes is for configuration save and restore purposes. There is an abstract mixin class which defines a set of pure virtual methods. Any class which is saveable inherits from the save/restore mixin class which automatically gives them the appropriate save/restore functionality.
But they may also inherit from other classes as part of their normal class structure, so it is quite common for these classes to use multiple inheritance in this respect.
An example of multiple inheritance:
class Animal
{
virtual void KeepCool() const = 0;
}
class Vertebrate
{
virtual void BendSpine() { };
}
class Dog : public Animal, public Vertebrate
{
void KeepCool() { Pant(); }
}
What is most important when doing any form of public inheritance (single or multiple) is to respect the is a relationship. A class should only inherit from one or more classes if it "is" one of those objects. If it simply "contains" one of those objects, aggregation or composition should be used instead.
The example above is well structured because a dog is an animal, and also a vertebrate.
Most people use multiple-inheritance in the context of applying multiple interfaces to a class. This is the approach Java and C#, among others, enforce.
C++ allows you to apply multiple base classes fairly freely, in an is-a relationship between types. So, you can treat a derived object like any of its base classes.
Another use, as LeopardSkinPillBoxHat points out, is in mix-ins. An excellent example of this is the Loki library, from Andrei Alexandrescu's book Modern C++ Design. He uses what he terms policy classes that specify the behavior or the requirements of a given class through inheritance.
Yet another use is one that simplifies a modular approach that allows API-independence through the use of sister-class delegation in the oft-dreaded diamond hierarchy.
The uses for MI are many. The potential for abuse is even greater.
Java has interfaces. C++ has not.
Therefore, multiple inheritance can be used to emulate the interface feature.
If you're a C# and Java programmer, every time you use a class that extends a base class but also implements a few interfaces, you are sort of admitting multiple inheritance can be useful in some situations.
I think it would be most useful for boilerplate code. For example, the IDisposable pattern is exactly the same for all classes in .NET. So why re-type that code over and over again?
Another example is ICollection. The vast majority of the interface methods are implemented exactly the same. There are only a couple of methods that are actually unique to your class.
Unfortunately multiple-inheritance is very easy to abuse. People will quickly start doing silly things like LabelPrinter class inherit from their TcpIpConnector class instead of merely contain it.
One case I worked on recently involved network enabled label printers. We need to print labels, so we have a class LabelPrinter. This class has virtual calls for printing several different labels. I also have a generic class for TCP/IP connected things, which can connect, send and receive.
So, when I needed to implement a printer, it inherited from both the LabelPrinter class and the TcpIpConnector class.
I think fmsf example is a bad idea. A car is not a tire or an engine. You should be using composition for that.
MI (of implementation or interface) can be used to add functionality. These are often called mixin classes.. Imagine you have a GUI. There is view class that handles drawing and a Drag&Drop class that handles dragging. If you have an object that does both you would have a class like
class DropTarget{
public void Drop(DropItem & itemBeingDropped);
...
}
class View{
public void Draw();
...
}
/* View you can drop items on */
class DropView:View,DropTarget{
}
It is true that composition of an interface (Java or C# like) plus forwarding to a helper can emulate many of the common uses of multiple inheritance (notably mixins). However this is done at the cost of that forwarding code being repeated (and violating DRY).
MI does open a number of difficult areas, and more recently some language designers have taken decisions that the potential pitfalls of MI outweigh the benefits.
Similarly one can argue against generics (heterogeneous containers do work, loops can be replaced with (tail) recursion) and almost any other feature of programming languages. Just because it is possible to work without a feature does not mean that that feature is valueless or cannot help to effectively express solutions.
A rich diversity of languages, and language families makes it easier for us as developers to pick good tools that solve the business problem at hand. My toolbox contains many items I rarely use, but on those occasions I do not want to treat everything as a nail.
An example of how our product uses mixin classes is for configuration save and restore purposes. There is an abstract mixin class which defines a set of pure virtual methods. Any class which is saveable inherits from the save/restore mixin class which automatically gives them the appropriate save/restore functionality.
This example doesn't really illustrate the usefulness of multiple inheritance. What being defined here is an INTERFACE. Multiple inheritance allows you to inherit behavior as well. Which is the point of mixins.
An example; because of a need to preserve backwards compatibility I have to implement my own serialization methods.
So every object gets a Read and Store method like this.
Public Sub Store(ByVal File As IBinaryWriter)
Public Sub Read(ByVal File As IBinaryReader)
I also want to be able to assign and clone object as well. So I would like this on every object.
Public Sub Assign(ByVal tObject As <Class_Name>)
Public Function Clone() As <Class_Name>
Now in VB6 I have this code repeated over and over again.
Public Assign(ByVal tObject As ObjectClass)
Me.State = tObject.State
End Sub
Public Function Clone() As ObjectClass
Dim O As ObjectClass
Set O = New ObjectClass
O.State = Me.State
Set Clone = 0
End Function
Public Property Get State() As Variant
StateManager.Clear
Me.Store StateManager
State = StateManager.Data
End Property
Public Property Let State(ByVal RHS As Variant)
StateManager.Data = RHS
Me.Read StateManager
End Property
Note that Statemanager is a stream that read and stores byte arrays.
This code is repeated dozens of times.
Now in .NET i am able to get around this by using a combination of generics and inheritance. My object under the .NET version get Assign, Clone, and State when they inherit from MyAppBaseObject. But I don't like the fact that every object inherits from MyAppBaseObject.
I rather just mix in the the Assign Clone interface AND BEHAVIOR. Better yet mix in separately the Read and Store interface then being able to mix in Assign and Clone. It would be cleaner code in my opinion.
But the times where I reuse behavior are DWARFED by the time I use Interface. This is because the goal of most object hierarchies are NOT about reusing behavior but precisely defining the relationship between different objects. Which interfaces are designed for. So while it would be nice that C# (or VB.NET) had some ability to do this it isn't a show stopper in my opinion.
The whole reason that this is even an issue that that C++ fumbled the ball at first when it came to the interface vs inheritance issue. When OOP debuted everybody thought that behavior reuse was the priority. But this proved to be a chimera and only useful for specific circumstances, like making a UI framework.
Later the idea of mixins (and other related concepts in aspect oriented programming) were developed. Multiple inheritance was found useful in creating mix-ins. But C# was developed just before this was widely recognized. Likely an alternative syntax will be developed to do this.
I suspect that in C++, MI is best use as part of a framework (the mix-in classes previously discussed). The only thing I know for sure is that every time I've tried to use it in my apps, I've ended up regretting the choice, and often tearing it out and replacing it with generated code.
MI is one more of those 'use it if you REALLY need it, but make sure you REALLY need it' tools.
The following example is mostly something I see often in C++: sometimes it may be necessary due to utility classes that you need but because of their design cannot be used through composition (at least not efficiently or without making the code even messier than falling back on mult. inheritance). A good example is you have an abstract base class A and a derived class B, and B also needs to be a kind of serializable class, so it has to derive from, let's say, another abstract class called Serializable. It's possible to avoid MI, but if Serializable only contains a few virtual methods and needs deep access to the private members of B, then it may be worth muddying the inheritance tree just to avoid making friend declarations and giving away access to B's internals to some helper composition class.
I had to use it today, actually...
Here was my situation - I had a domain model represented in memory where an A contained zero or more Bs(represented in an array), each B has zero or more Cs, and Cs to Ds. I couldn't change the fact that they were arrays (the source for these arrays were from automatically generated code from the build process). Each instance needed to keep track of which index in the parent array they belonged in. They also needed to keep track of the instance of their parent (too much detail as to why). I wrote something like this (there was more to it, and this is not syntactically correct, it's just an example):
class Parent
{
add(Child c)
{
children.add(c);
c.index = children.Count-1;
c.parent = this;
}
Collection<Child> children
}
class Child
{
Parent p;
int index;
}
Then, for the domain types, I did this:
class A : Parent
class B : Parent, Child
class C : Parent, Child
class D : Child
The actually implementation was in C# with interfaces and generics, and I couldn't do the multiple inheritance like I would have if the language supported it (some copy paste had to be done). So, I thought I'd search SO to see what people think of multiple inheritance, and I got your question ;)
I couldn't use your solution of the .anotherClass, because of the implementation of add for Parent (references this - and I wanted this to not be some other class).
It got worse because the generated code had A subclass something else that was neither a parent or a child...more copy paste.
Could someone please demystify interfaces for me or point me to some good examples? I keep seeing interfaces popup here and there, but I haven't ever really been exposed to good explanations of interfaces or when to use them.
I am talking about interfaces in a context of interfaces vs. abstract classes.
Interfaces allow you to program against a "description" instead of a type, which allows you to more-loosely associate elements of your software.
Think of it this way: You want to share data with someone in the cube next to you, so you pull out your flash stick and copy/paste. You walk next door and the guy says "is that USB?" and you say yes - all set. It doesn't matter the size of the flash stick, nor the maker - all that matters is that it's USB.
In the same way, interfaces allow you to generisize your development. Using another analogy - imagine you wanted to create an application that virtually painted cars. You might have a signature like this:
public void Paint(Car car, System.Drawing.Color color)...
This would work until your client said "now I want to paint trucks" so you could do this:
public void Paint (Vehicle vehicle, System.Drawing.Color color)...
this would broaden your app... until your client said "now I want to paint houses!" What you could have done from the very beginning is created an interface:
public interface IPaintable{
void Paint(System.Drawing.Color color);
}
...and passed that to your routine:
public void Paint(IPaintable item, System.Drawing.Color color){
item.Paint(color);
}
Hopefully this makes sense - it's a pretty simplistic explanation but hopefully gets to the heart of it.
Interfaces establish a contract between a class and the code that calls it. They also allow you to have similar classes that implement the same interface but do different actions or events and not have to know which you are actually working with. This might make more sense as an example so let me try one here.
Say you have a couple classes called Dog, Cat, and Mouse. Each of these classes is a Pet and in theory you could inherit them all from another class called Pet but here's the problem. Pets in and of themselves don't do anything. You can't go to the store and buy a pet. You can go and buy a dog or a cat but a pet is an abstract concept and not concrete.
So You know pets can do certain things. They can sleep, or eat, etc. So you define an interface called IPet and it looks something like this (C# syntax)
public interface IPet
{
void Eat(object food);
void Sleep(int duration);
}
Each of your Dog, Cat, and Mouse classes implement IPet.
public class Dog : IPet
So now each of those classes has to have it's own implementation of Eat and Sleep. Yay you have a contract... Now what's the point.
Next let's say you want to make a new object called PetStore. And this isn't a very good PetStore so they basically just sell you a random pet (yes i know this is a contrived example).
public class PetStore
{
public static IPet GetRandomPet()
{
//Code to return a random Dog, Cat, or Mouse
}
}
IPet myNewRandomPet = PetStore.GetRandomPet();
myNewRandomPet.Sleep(10);
The problem is you don't know what type of pet it will be. Thanks to the interface though you know whatever it is it will Eat and Sleep.
So this answer may not have been helpful at all but the general idea is that interfaces let you do neat stuff like Dependency Injection and Inversion of Control where you can get an object, have a well defined list of stuff that object can do without ever REALLY knowing what the concrete type of that object is.
The easiest answer is that interfaces define a what your class can do. It's a "contract" that says that your class will be able to do that action.
Public Interface IRollOver
Sub RollOver()
End Interface
Public Class Dog Implements IRollOver
Public Sub RollOver() Implements IRollOver.RollOver
Console.WriteLine("Rolling Over!")
End Sub
End Class
Public Sub Main()
Dim d as New Dog()
Dim ro as IRollOver = TryCast(d, IRollOver)
If ro isNot Nothing Then
ro.RollOver()
End If
End Sub
Basically, you are guaranteeing that the Dog class always has the ability to roll over as long as it continues to implement that Interface. Should cats ever gain the ability to RollOver(), they too could implement that interface, and you can treat both Dogs and Cats homogeneously when asking them to RollOver().
When you drive a friend's car, you more or less know how to do that. This is because conventional cars all have a very similar interface: steering wheel, pedals, and so forth. Think of this interface as a contract between car manufacturers and drivers. As a driver (the user/client of the interface in software terms), you don't need to learn the particulars of different cars to be able to drive them: e.g., all you need to know is that turning the steering wheel makes the car turn. As a car manufacturer (the provider of an implementation of the interface in software terms) you have a clear idea what your new car should have and how it should behave so that drivers can use them without much extra training. This contract is what people in software design refer to as decoupling (the user from the provider) -- the client code is in terms of using an interface rather than a particular implementation thereof and hence doesn't need to know the details of the objects implementing the interface.
Interfaces are a mechanism to reduce coupling between different, possibly disparate parts of a system.
From a .NET perspective
The interface definition is a list of operations and/or properties.
Interface methods are always public.
The interface itself doesn't have to be public.
When you create a class that implements the interface, you must provide either an explicit or implicit implementation of all methods and properties defined by the interface.
Further, .NET has only single inheritance, and interfaces are a necessity for an object to expose methods to other objects that aren't aware of, or lie outside of its class hierarchy. This is also known as exposing behaviors.
An example that's a little more concrete:
Consider is we have many DTO's (data transfer objects) that have properties for who updated last, and when that was. The problem is that not all the DTO's have this property because it's not always relevant.
At the same time we desire a generic mechanism to guarantee these properties are set if available when submitted to the workflow, but the workflow object should be loosely coupled from the submitted objects. i.e. the submit workflow method shouldn't really know about all the subtleties of each object, and all objects in the workflow aren't necessarily DTO objects.
// First pass - not maintainable
void SubmitToWorkflow(object o, User u)
{
if (o is StreetMap)
{
var map = (StreetMap)o;
map.LastUpdated = DateTime.UtcNow;
map.UpdatedByUser = u.UserID;
}
else if (o is Person)
{
var person = (Person)o;
person.LastUpdated = DateTime.Now; // Whoops .. should be UtcNow
person.UpdatedByUser = u.UserID;
}
// Whoa - very unmaintainable.
In the code above, SubmitToWorkflow() must know about each and every object. Additionally, the code is a mess with one massive if/else/switch, violates the don't repeat yourself (DRY) principle, and requires developers to remember copy/paste changes every time a new object is added to the system.
// Second pass - brittle
void SubmitToWorkflow(object o, User u)
{
if (o is DTOBase)
{
DTOBase dto = (DTOBase)o;
dto.LastUpdated = DateTime.UtcNow;
dto.UpdatedByUser = u.UserID;
}
It is slightly better, but it is still brittle. If we want to submit other types of objects, we need still need more case statements. etc.
// Third pass pass - also brittle
void SubmitToWorkflow(DTOBase dto, User u)
{
dto.LastUpdated = DateTime.UtcNow;
dto.UpdatedByUser = u.UserID;
It is still brittle, and both methods impose the constraint that all the DTOs have to implement this property which we indicated wasn't universally applicable. Some developers might be tempted to write do-nothing methods, but that smells bad. We don't want classes pretending they support update tracking but don't.
Interfaces, how can they help?
If we define a very simple interface:
public interface IUpdateTracked
{
DateTime LastUpdated { get; set; }
int UpdatedByUser { get; set; }
}
Any class that needs this automatic update tracking can implement the interface.
public class SomeDTO : IUpdateTracked
{
// IUpdateTracked implementation as well as other methods for SomeDTO
}
The workflow method can be made to be a lot more generic, smaller, and more maintainable, and it will continue to work no matter how many classes implement the interface (DTOs or otherwise) because it only deals with the interface.
void SubmitToWorkflow(object o, User u)
{
IUpdateTracked updateTracked = o as IUpdateTracked;
if (updateTracked != null)
{
updateTracked.LastUpdated = DateTime.UtcNow;
updateTracked.UpdatedByUser = u.UserID;
}
// ...
We can note the variation void SubmitToWorkflow(IUpdateTracked updateTracked, User u) would guarantee type safety, however it doesn't seem as relevant in these circumstances.
In some production code we use, we have code generation to create these DTO classes from the database definition. The only thing the developer does is have to create the field name correctly and decorate the class with the interface. As long as the properties are called LastUpdated and UpdatedByUser, it just works.
Maybe you're asking What happens if my database is legacy and that's not possible? You just have to do a little more typing; another great feature of interfaces is they can allow you to create a bridge between the classes.
In the code below we have a fictitious LegacyDTO, a pre-existing object having similarly-named fields. It's implementing the IUpdateTracked interface to bridge the existing, but differently named properties.
// Using an interface to bridge properties
public class LegacyDTO : IUpdateTracked
{
public int LegacyUserID { get; set; }
public DateTime LastSaved { get; set; }
public int UpdatedByUser
{
get { return LegacyUserID; }
set { LegacyUserID = value; }
}
public DateTime LastUpdated
{
get { return LastSaved; }
set { LastSaved = value; }
}
}
You might thing Cool, but isn't it confusing having multiple properties? or What happens if there are already those properties, but they mean something else? .NET gives you the ability to explicitly implement the interface.
What this means is that the IUpdateTracked properties will only be visible when we're using a reference to IUpdateTracked. Note how there is no public modifier on the declaration, and the declaration includes the interface name.
// Explicit implementation of an interface
public class YetAnotherObject : IUpdatable
{
int IUpdatable.UpdatedByUser
{ ... }
DateTime IUpdatable.LastUpdated
{ ... }
Having so much flexibility to define how the class implements the interface gives the developer a lot of freedom to decouple the object from methods that consume it. Interfaces are a great way to break coupling.
There is a lot more to interfaces than just this. This is just a simplified real-life example that utilizes one aspect of interface based programming.
As I mentioned earlier, and by other responders, you can create methods that take and/or return interface references rather than a specific class reference. If I needed to find duplicates in a list, I could write a method that takes and returns an IList (an interface defining operations that work on lists) and I'm not constrained to a concrete collection class.
// Decouples the caller and the code as both
// operate only on IList, and are free to swap
// out the concrete collection.
public IList<T> FindDuplicates( IList<T> list )
{
var duplicates = new List<T>()
// TODO - write some code to detect duplicate items
return duplicates;
}
Versioning caveat
If it's a public interface, you're declaring I guarantee interface x looks like this! And once you have shipped code and published the interface, you should never change it. As soon as consumer code starts to rely on that interface, you don't want to break their code in the field.
See this Haacked post for a good discussion.
Interfaces versus abstract (base) classes
Abstract classes can provide implementation whereas Interfaces cannot. Abstract classes are in some ways more flexible in the versioning aspect if you follow some guidelines like the NVPI (Non-Virtual Public Interface) pattern.
It's worth reiterating that in .NET, a class can only inherit from a single class, but a class can implement as many interfaces as it likes.
Dependency Injection
The quick summary of interfaces and dependency injection (DI) is that the use of interfaces enables developers to write code that is programmed against an interface to provide services. In practice you can end up with a lot of small interfaces and small classes, and one idea is that small classes that do one thing and only one thing are much easier to code and maintain.
class AnnualRaiseAdjuster
: ISalaryAdjuster
{
AnnualRaiseAdjuster(IPayGradeDetermination payGradeDetermination) { ... }
void AdjustSalary(Staff s)
{
var payGrade = payGradeDetermination.Determine(s);
s.Salary = s.Salary * 1.01 + payGrade.Bonus;
}
}
In brief, the benefit shown in the above snippet is that the pay grade determination is just injected into the annual raise adjuster. How pay grade is determined doesn't actually matter to this class. When testing, the developer can mock pay grade determination results to ensure the salary adjuster functions as desired. The tests are also fast because the test is only testing the class, and not everything else.
This isn't a DI primer though as there are whole books devoted to the subject; the above example is very simplified.
This is a rather "long" subject, but let me try to put it simple.
An interface is -as "they name it"- a Contract. But forget about that word.
The best way to understand them is through some sort of pseudo-code example. That's how I understood them long time ago.
Suppose you have an app that processes Messages. A Message contains some stuff, like a subject, a text, etc.
So you write your MessageController to read a database, and extract messages. It's very nice until you suddenly hear that Faxes will be also implemented soon. So you will now have to read "Faxes" and process them as messages!
This could easily turn into a Spagetti code. So what you do instead of having a MessageController than controls "Messages" only, you make it able to work with an interface called IMessage (the I is just common usage, but not required).
Your IMessage interface, contains some basic data you need to make sure that you're able to process the Message as such.
So when you create your EMail, Fax, PhoneCall classes, you make them Implement the Interface called IMessage.
So in your MessageController, you can have a method called like this:
private void ProcessMessage(IMessage oneMessage)
{
DoSomething();
}
If you had not used Interfaces, you'd have to have:
private void ProcessEmail(Email someEmail);
private void ProcessFax(Fax someFax);
etc.
So, by using a common interface, you just made sure that the ProcessMessage method will be able to work with it, no matter if it was a Fax, an Email a PhoneCall, etc.
Why or how?
Because the interface is a contract that specifies some things you must adhere (or implement) in order to be able to use it. Think of it as a badge. If your object "Fax" doesn't have the IMessage interface, then your ProcessMessage method wouldn't be able to work with that, it will give you an invalid type, because you're passing a Fax to a method that expects an IMessage object.
Do you see the point?
Think of the interface as a "subset" of methods and properties that you will have available, despite the real object type. If the original object (Fax, Email, PhoneCall, etc) implements that interface, you can safety pass it across methods that need that Interface.
There's more magic hidden in there, you can CAST the interfaces back to their original objects:
Fax myFax = (Fax)SomeIMessageThatIReceive;
The ArrayList() in .NET 1.1 had a nice interface called IList. If you had an IList (very "generic") you could transform it into an ArrayList:
ArrayList ar = (ArrayList)SomeIList;
And there are thousands of samples out there in the wild.
Interfaces like ISortable, IComparable, etc., define the methods and properties you must implement in your class in order to achieve that functionality.
To expand our sample, you could have a List<> of Emails, Fax, PhoneCall, all in the same List, if the Type is IMessage, but you couldn't have them all together if the objects were simply Email, Fax, etc.
If you wanted to sort (or enumerate for example) your objects, you'd need them to implement the corresponding interface. In the .NET sample, if you have a list of "Fax" objects and want to be able to sort them by using MyList.Sort(), you need to make your fax class like this:
public class Fax : ISorteable
{
//implement the ISorteable stuff here.
}
I hope this gives you a hint. Other users will possibly post other good examples. Good luck! and Embrace the power of INterfaces.
warning: Not everything is good about interfaces, there are some issues with them, OOP purists will start a war on this. I shall remain aside. One drawback of an Interfce (in .NET 2.0 at least) is that you cannot have PRIVATE members, or protected, it must be public. This makes some sense, but sometimes you wish you could simply declare stuff as private or protected.
In addition to the function interfaces have within programming languages, they also are a powerful semantic tool when expressing design ideas to other people.
A code base with well-designed interfaces is suddenly a lot easier to discuss. "Yes, you need a CredentialsManager to register new remote servers." "Pass a PropertyMap to ThingFactory to get a working instance."
Ability to address a complex thing with a single word is pretty useful.
Interfaces let you code against objects in a generic way. For instance, say you have a method that sends out reports. Now say you have a new requirement that comes in where you need to write a new report. It would be nice if you could reuse the method you already had written right? Interfaces makes that easy:
interface IReport
{
string RenderReport();
}
class MyNewReport : IReport
{
public string RenderReport()
{
return "Hello World Report!";
}
}
class AnotherReport : IReport
{
public string RenderReport()
{
return "Another Report!";
}
}
//This class can process any report that implements IReport!
class ReportEmailer()
{
public void EmailReport(IReport report)
{
Email(report.RenderReport());
}
}
class MyApp()
{
void Main()
{
//create specific "MyNewReport" report using interface
IReport newReport = new MyNewReport();
//create specific "AnotherReport" report using interface
IReport anotherReport = new AnotherReport();
ReportEmailer reportEmailer = new ReportEmailer();
//emailer expects interface
reportEmailer.EmailReport(newReport);
reportEmailer.EmailReport(anotherReport);
}
}
Interfaces are also key to polymorphism, one of the "THREE PILLARS OF OOD".
Some people touched on it above, polymorphism just means a given class can take on different "forms". Meaning, if we have two classes, "Dog" and "Cat" and both implement the interface "INeedFreshFoodAndWater" (hehe) - your code can do something like this (pseudocode):
INeedFreshFoodAndWater[] array = new INeedFreshFoodAndWater[];
array.Add(new Dog());
array.Add(new Cat());
foreach(INeedFreshFoodAndWater item in array)
{
item.Feed();
item.Water();
}
This is powerful because it allows you to treat different classes of objects abstractly, and allows you to do things like make your objects more loosely coupled, etc.
OK, so it's about abstract classes vs. interfaces...
Conceptually, abstract classes are there to be used as base classes. Quite often they themselves already provide some basic functionality, and the subclasses have to provide their own implementation of the abstract methods (those are the methods which aren't implemented in the abstract base class).
Interfaces are mostly used for decoupling the client code from the details of a particular implementation. Also, sometimes the ability to switch the implementation without changing the client code makes the client code more generic.
On the technical level, it's harder to draw the line between abstract classes and interfaces, because in some languages (e.g., C++), there's no syntactic difference, or because you could also use abstract classes for the purposes of decoupling or generalization. Using an abstract class as an interface is possible because every base class, by definition, defines an interface that all of its subclasses should honor (i.e., it should be possible to use a subclass instead of a base class).
Interfaces are a way to enforce that an object implements a certain amount of functionality, without having to use inheritance (which leads to strongly coupled code, instead of loosely coupled which can be achieved through using interfaces).
Interfaces describe the functionality, not the implementation.
Most of the interfaces you come across are a collection of method and property signatures. Any one who implements an interface must provide definitions to what ever is in the interface.
Simply put: An interface is a class that methods defined but no implementation in them. In contrast an abstract class has some of the methods implemented but not all.
Think of an interface as a contract. When a class implements an interface, it is essentially agreeing to honor the terms of that contract. As a consumer, you only care that the objects you have can perform their contractual duties. Their inner workings and details aren't important.
One good reason for using an interface vs. an abstract class in Java is that a subclass cannot extend multiple base classes, but it CAN implement multiple interfaces.
Java does not allow multiple inheritance (for very good reasons, look up dreadful diamond) but what if you want to have your class supply several sets of behavior? Say you want anyone who uses it to know it can be serialized, and also that it can paint itself on the screen. the answer is to implement two different interfaces.
Because interfaces contain no implementation of their own and no instance members it is safe to implement several of them in the same class with no ambiguities.
The down side is that you will have to have the implementation in each class separately. So if your hierarchy is simple and there are parts of the implementation that should be the same for all the inheriting classes use an abstract class.
Assuming you're referring to interfaces in statically-typed object-oriented languages, the primary use is in asserting that your class follows a particular contract or protocol.
Say you have:
public interface ICommand
{
void Execute();
}
public class PrintSomething : ICommand
{
OutputStream Stream { get; set; }
String Content {get; set;}
void Execute()
{
Stream.Write(content);
}
}
Now you have a substitutable command structure. Any instance of a class that implements IExecute can be stored in a list of some sort, say something that implements IEnumerable and you can loop through that and execute each one, knowing that each object will Just Do The Right Thing. You can create a composite command by implementing CompositeCommand which will have its own list of commands to run, or a LoopingCommand to run a set of commands repeatedly, then you'll have most of a simple interpreter.
When you can reduce a set of objects to a behavior that they all have in common, you might have cause to extract an interface. Also, sometimes you can use interfaces to prevent objects from accidentally intruding on the concerns of that class; for example, you may implement an interface that only allows clients to retrieve, rather than change data in your object, and have most objects receive only a reference to the retrieval interface.
Interfaces work best when your interfaces are relatively simple and make few assumptions.
Look up the Liskov subsitution principle to make more sense of this.
Some statically-typed languages like C++ don't support interfaces as a first-class concept, so you create interfaces using pure abstract classes.
Update
Since you seem to be asking about abstract classes vs. interfaces, here's my preferred oversimplification:
Interfaces define capabilities and features.
Abstract classes define core functionality.
Typically, I do an extract interface refactoring before I build an abstract class. I'm more likely to build an abstract class if I think there should be a creational contract (specifically, that a specific type of constructor should always be supported by subclasses). However, I rarely use "pure" abstract classes in C#/java. I'm far more likely to implement a class with at least one method containing meaningful behavior, and use abstract methods to support template methods called by that method. Then the abstract class is a base implementation of a behavior, which all concrete subclasses can take advantage of without having to reimplement.
Simple answer: An interface is a bunch of method signatures (+ return type). When an object says it implements an interface, you know it exposes that set of methods.
Interfaces are a way to implement conventions in a way that is still strongly typed and polymorphic.
A good real world example would be IDisposable in .NET. A class that implements the IDisposable interface forces that class to implement the Dispose() method. If the class doesn't implement Dispose() you'll get a compiler error when trying to build. Additionally, this code pattern:
using (DisposableClass myClass = new DisposableClass())
{
// code goes here
}
Will cause myClass.Dispose() to be executed automatically when execution exits the inner block.
However, and this is important, there is no enforcement as to what your Dispose() method should do. You could have your Dispose() method pick random recipes from a file and email them to a distribution list, the compiler doesn't care. The intent of the IDisposable pattern is to make cleaning up resources easier. If instances of a class will hold onto file handles then IDisposable makes it very easy to centralize the deallocation and cleanup code in one spot and to promote a style of use which ensures that deallocation always occurs.
And that's the key to interfaces. They are a way to streamline programming conventions and design patterns. Which, when used correctly, promotes simpler, self-documenting code which is easier to use, easier to maintain, and more correct.
Here is a db related example I often use. Let us say you have an object and a container object like an list. Let us assume that sometime you might want to store the objects in a particular sequence. Assume that the sequence is not related to the position in the array but instead that the objects are a subset of a larger set of objects and the sequence position is related to the database sql filtering.
To keep track of your customized sequence positions you could make your object implement a custom interface. The custom interface could mediate the organizational effort required to maintain such sequences.
For example, the sequence you are interested in has nothing to do with primary keys in the records. With the object implementing the interface you could say myObject.next() or myObject.prev().
I have had the same problem as you and I find the "contract" explanation a bit confusing.
If you specify that a method takes an IEnumerable interface as an in-parameter you could say that this is a contract specifying that the parameter must be of a type that inherits from the IEnumerable interface and hence supports all methods specified in the IEnumerable interface. The same would be true though if we used an abstract class or a normal class. Any object that inherits from those classes would be ok to pass in as a parameter. You would in any case be able to say that the inherited object supports all public methods in the base class whether the base class is a normal class, an abstract class or an interface.
An abstract class with all abstract methods is basically the same as an interface so you could say an interface is simply a class without implemented methods. You could actually drop interfaces from the language and just use abstract class with only abstract methods instead. I think the reason we separate them is for semantic reasons but for coding reasons I don't see the reason and find it just confusing.
Another suggestion could be to rename the interface to interface class as the interface is just another variation of a class.
In certain languages there are subtle differences that allows a class to inherit only 1 class but multiple interfaces while in others you could have many of both, but that is another issue and not directly related I think
The simplest way to understand interfaces is to start by considering what class inheritance means. It includes two aspects:
Members of a derived class can use public or protected members of a base class as their own.
Members of a derived class can be used by code which expects a member of the base class (meaning they are substitutable).
Both of these features are useful, but because it is difficult to allow a class to use members of more than one class as its own, many languages and frameworks only allow classes to inherit from a single base class. On the other hand, there is no particular difficulty with having a class be substitutable for multiple other unrelated things.
Further, because the first benefit of inheritance can be largely achieved via encapsulation, the relative benefit from allowing multiple-inheritance of the first type is somewhat limited. On the other hand, being able to substitute an object for multiple unrelated types of things is a useful ability which cannot be readily achieved without language support.
Interfaces provide a means by which a language/framework can allow programs to benefit from the second aspect of inheritance for multiple base types, without requiring it to also provide the first.
Interface is like a fully abstract class. That is, an abstract class with only abstract members. You can also implement multiple interfaces, it's like inheriting from multiple fully abstract classes. Anyway.. this explanation only helps if you understand what an abstract class is.
Like others have said here, interfaces define a contract (how the classes who use the interface will "look") and abstract classes define shared functionality.
Let's see if the code helps:
public interface IReport
{
void RenderReport(); // This just defines the method prototype
}
public abstract class Reporter
{
protected void DoSomething()
{
// This method is the same for every class that inherits from this class
}
}
public class ReportViolators : Reporter, IReport
{
public void RenderReport()
{
// Some kind of implementation specific to this class
}
}
public class ClientApp
{
var violatorsReport = new ReportViolators();
// The interface method
violatorsReport.RenderReport();
// The abstract class method
violatorsReport.DoSomething();
}
Interfaces require any class that implements them to contain the methods defined in the interface.
The purpose is so that, without having to see the code in a class, you can know if it can be used for a certain task. For example, the Integer class in Java implements the comparable interface, so, if you only saw the method header (public class String implements Comparable), you would know that it contains a compareTo() method.
In your simple case, you could achieve something similar to what you get with interfaces by using a common base class that implements show() (or perhaps defines it as abstract). Let me change your generic names to something more concrete, Eagle and Hawk instead of MyClass1 and MyClass2. In that case you could write code like
Bird bird = GetMeAnInstanceOfABird(someCriteriaForSelectingASpecificKindOfBird);
bird.Fly(Direction.South, Speed.CruisingSpeed);
That lets you write code that can handle anything that is a Bird. You could then write code that causes the Bird to do its thing (fly, eat, lay eggs, and so forth) that acts on an instance it treats as a Bird. That code would work whether Bird is really an Eagle, Hawk, or anything else that derives from Bird.
That paradigm starts to get messy, though, when you don't have a true is a relationship. Say you want to write code that flies things around in the sky. If you write that code to accept a Bird base class, it suddenly becomes hard to evolve that code to work on a JumboJet instance, because while a Bird and a JumboJet can certainly both fly, a JumboJet is most certainly not a Bird.
Enter the interface.
What Bird (and Eagle, and Hawk) do have in common is that they can all fly. If you write the above code instead to act on an interface, IFly, that code can be applied to anything that provides an implementation to that interface.
The Open/Closed Principle states that software entities (classes, modules, etc.) should be open for extension, but closed for modification. What does this mean, and why is it an important principle of good object-oriented design?
It means that you should put new code in new classes/modules. Existing code should be modified only for bug fixing. New classes can reuse existing code via inheritance.
Open/closed principle is intended to mitigate risk when introducing new functionality. Since you don't modify existing code you can be assured that it wouldn't be broken. It reduces maintenance cost and increases product stability.
Specifically, it is about a "Holy Grail" of design in OOP of making an entity extensible enough (through its individual design or through its participation in the architecture) to support future unforseen changes without rewriting its code (and sometimes even without re-compiling **).
Some ways to do this include Polymorphism/Inheritance, Composition, Inversion of Control (a.k.a. DIP), Aspect-Oriented Programming, Patterns such as Strategy, Visitor, Template Method, and many other principles, patterns, and techniques of OOAD.
** See the 6 "package principles", REP, CCP, CRP, ADP, SDP, SAP
More specifically than DaveK, it usually means that if you want to add additional functionality, or change the functionality of a class, create a subclass instead of changing the original. This way, anyone using the parent class does not have to worry about it changing later on. Basically, it's all about backwards compatibility.
Another really important principle of object-oriented design is loose coupling through a method interface. If the change you want to make does not affect the existing interface, it really is pretty safe to change. For example, to make an algorithm more efficient. Object-oriented principles need to be tempered by common sense too :)
Open Closed Principle is very important in object oriented programming and it's one of the SOLID principles.
As per this, a class should be open for extension and closed for
modification. Let us understand why.
class Rectangle {
public int width;
public int lenth;
}
class Circle {
public int radius;
}
class AreaService {
public int areaForRectangle(Rectangle rectangle) {
return rectangle.width * rectangle.lenth;
}
public int areaForCircle(Circle circle) {
return (22 / 7) * circle.radius * circle.radius;
}
}
If you look at the above design, we can clearly observe that it's not
following Open/Closed Principle. Whenever there is a new
shape(Tiangle, Square etc.), AreaService has to be modified.
With Open/Closed Principle:
interface Shape{
int area();
}
class Rectangle implements Shape{
public int width;
public int lenth;
#Override
public int area() {
return lenth * width;
}
}
class Cirle implements Shape{
public int radius;
#Override
public int area() {
return (22/7) * radius * radius;
}
}
class AreaService {
int area(Shape shape) {
return shape.area();
}
}
Whenever there is new shape like Triangle, Square etc. you can easily
accommodate the new shapes without modifying existing classes. With
this design, we can ensure that existing code doesn't impact.
Software entities should be open for extension but closed for modification
That means any class or module should be written in a way that it can be used as is, can be extended, but neve modified
Bad Example in Javascript
var juiceTypes = ['Mango','Apple','Lemon'];
function juiceMaker(type){
if(juiceTypes.indexOf(type)!=-1)
console.log('Here is your juice, Have a nice day');
else
console.log('sorry, Error happned');
}
exports.makeJuice = juiceMaker;
Now if you want to add Another Juice type, you have to edit the module itself, By this way, we are breaking OCP .
Good Example in Javascript
var juiceTypes = [];
function juiceMaker(type){
if(juiceTypes.indexOf(type)!=-1)
console.log('Here is your juice, Have a nice day');
else
console.log('sorry, Error happned');
}
function addType(typeName){
if(juiceTypes.indexOf(typeName)==-1)
juiceTypes.push(typeName);
}
function removeType(typeName){
let index = juiceTypes.indexOf(typeName)
if(index!==-1)
juiceTypes.splice(index,1);
}
exports.makeJuice = juiceMaker;
exports.addType = addType;
exports.removeType = removeType;
Now, you can add new juice types from outside the module without editing the same module.
Let's break down the question in three parts to make it easier to understand the various concepts.
Reasoning Behind Open-Closed Principle
Consider an example in the code below. Different vehicles are serviced in a different manner. So, we have different classes for Bike and Car because the strategy to service a Bike is different from the strategy to service a Car. The Garage class accepts various kinds of vehicles for servicing.
Problem of Rigidity
Observe the code and see how the Garage class shows the signs of rigidity when it comes to introducing a new functionality:
class Bike {
public void service() {
System.out.println("Bike servicing strategy performed.");
}
}
class Car {
public void service() {
System.out.println("Car servicing strategy performed.");
}
}
class Garage {
public void serviceBike(Bike bike) {
bike.service();
}
public void serviceCar(Car car) {
car.service();
}
}
As you may have noticed, whenever some new vehicle like Truck or Bus is to be serviced, the Garage will need to be modified to define some new methods like serviceTruck() and serviceBus(). That means the Garage class must know every possible vehicle like Bike, Car, Bus, Truck and so on. So, it violates the open-closed principle by being open for modification. Also it's not open for extension because to extend the new functionality, we need to modify the class.
Meaning Behind Open-Closed Principle
Abstraction
To solve the problem of rigidity in the code above we can use the open-closed principle. That means we need to make the Garage class dumb by taking away the implementation details of servicing of every vehicle that it knows. In other words we should abstract the implementation details of the servicing strategy for each concrete type like Bike and Car.
To abstract the implementation details of the servicing strategies for various types of vehicles we use an interface called Vehicle and have an abstract method service() in it.
Polymorphism
At the same time, we also want the Garage class to accept many forms of the vehicle, like Bus, Truck and so on, not just Bike and Car. To do that, the open-closed principle uses polymorphism (many forms).
For the Garage class to accept many forms of the Vehicle, we change the signature of its method to service(Vehicle vehicle) { } to accept the interface Vehicle instead of the actual implementation like Bike, Car etc. We also remove the multiple methods from the class as just one method will accept many forms.
interface Vehicle {
void service();
}
class Bike implements Vehicle {
#Override
public void service() {
System.out.println("Bike servicing strategy performed.");
}
}
class Car implements Vehicle {
#Override
public void service() {
System.out.println("Car servicing strategy performed.");
}
}
class Garage {
public void service(Vehicle vehicle) {
vehicle.service();
}
}
Importance of Open-Closed Principle
Closed for modification
As you can see in the code above, now the Garage class has become closed for modification because now it doesn't know about the implementation details of servicing strategies for various types of vehicles and can accept any type of new Vehicle. We just have to extend the new vehicle from the Vehicle interface and send it to the Garage. That's it! We don't need to change any code in the Garage class.
Another entity that's closed for modification is our Vehicle interface.
We don't have to change the interface to extend the functionality of our software.
Open for extension
The Garage class now becomes open for extension in the context that it will support the new types of Vehicle, without the need for modifying.
Our Vehicle interface is open for extension because to introduce any new vehicle, we can extend from the Vehicle interface and provide a new implementation with a strategy for servicing that particular vehicle.
Strategy Design Pattern
Did you notice that I used the word strategy multiple times? That's because this is also an example of the Strategy Design Pattern. We can implement different strategies for servicing different types of Vehicles by extending it. For example, servicing a Truck has a different strategy from the strategy of servicing a Bus. So we implement these strategies inside the different derived classes.
The strategy pattern allows our software to be flexible as the requirements change over time. Whenever the client changes their strategy, just derive a new class for it and provide it to the existing component, no need to change other stuff! The open-closed principle plays an important role in implementing this pattern.
That's it! Hope that helps.
It's the answer to the fragile base class problem, which says that seemingly innocent modifications to base classes may have unintended consequences to inheritors that depended on the previous behavior. So you have to be careful to encapsulate what you don't want relied upon so that the derived classes will obey the contracts defined by the base class. And once inheritors exist, you have to be really careful with what you change in the base class.
Purpose of the Open closed Principle in SOLID Principles is to
reduce the cost of a business change requirement.
reduce testing of existing code.
Open Closed Principle states that we should try not to alter existing
code while adding new functionalities. It basically means that
existing code should be open for extension and closed for
modification(unless there is a bug in existing code). Altering existing code while adding new functionalities requires existing features to be tested again.
Let me explain this by taking AppLogger util class.
Let's say we have a requirement to log application wide errors to a online tool called Firebase. So we create below class and use it in 1000s of places to log API errors, out of memory errors etc.
open class AppLogger {
open fun logError(message: String) {
// reporting error to Firebase
FirebaseAnalytics.logException(message)
}
}
Let's say after sometime, we add Payment Feature to the app and there is a new requirement which states that only for Payment related errors we have to use a new reporting tool called Instabug and also continue reporting errors to Firebase just like before for all features including Payment.
Now we can achieve this by putting an if else condition inside our existing method
fun logError(message: String, origin: String) {
if (origin == "Payment") {
//report to both Firebase and Instabug
FirebaseAnalytics.logException(message)
InstaBug.logException(message)
} else {
// otherwise report only to Firebase
FirebaseAnalytics.logException(message)
}
}
Problem with this approach is that it violates Single Responsibility Principle which states that a method should do only one thing. Another way of putting it is a method should have only one reason to change. With this approach there are two reasons for this method to change (if & else blocks).
A better approach would be to create a new Logger class by inheriting the existing Logger class like below.
class InstaBugLogger : AppLogger() {
override fun logError(message: String) {
super.logError(message) // This uses AppLogger.logError to report to Firebase.
InstaBug.logException(message) //Reporting to Instabug
}
}
Now all we have to do is use InstaBugLogger.logError() in Payment features to log errors to both Instabug and Firebase. This way we reduce/isolate the testing of new error reporting requirement to only Payment feature as code changes are done only in Payment Feature. The rest of the application features need not be tested as there are no code changes done to the existing Logger.
The principle means that it should easy to add new functionality without having to change existing, stable, and tested functionality, saving both time and money.
Often, polymorhism, for instance using interfaces, is a good tool for achieving this.
An additional rule of thumb for conforming to OCP is to make base classes abstract with respect to functionality provided by derived classes. Or as Scott Meyers says 'Make Non-leaf classes abstract'.
This means having unimplemented methods in the base class and only implement these methods in classes which themselves have no sub classes. Then the client of the base class cannot rely on a particular implementation in the base class since there is none.
I just want to emphasize that "Open/Closed", even though being obviously useful in OO programming, is a healthy method to use in all aspects of development. For instance, in my own experience it's a great painkiller to use "Open/Closed" as much as possible when working with plain C.
/Robert
This means that the OO software should be built upon, but not changed intrinsically. This is good because it ensures reliable, predictable performance from the base classes.
I was recently given an additional idea of what this principle entails: that the Open-Closed Principle describes at once a way of writing code, as well as an end-result of writing code in a resilient way.
I like to think of Open/Closed split up in two closely-related parts:
Code that is Open to change can either change its behavior to correctly handle its inputs, or requires minimum modification to provide for new usage scenarios.
Code that is Closed for modification does not require much if any human intervention to handle new usage scenarios. The need simply does not exist.
Thus, code that exhibits Open/Closed behavior (or, if you prefer, fulfills the Open/Closed Principle) requires minimal or no modification in response to usage scenarios beyond what it was originally built for.
As far as implementation is concerned? I find that the commonly-stated interpretation, "Open/Closed refers to code being polymorphic!" to be at best an incomplete statement. Polymorphism in code is one tool to achieve this sort of behavior; Inheritance, Implementation...really, every object-oriented design principle is necessary to write code that is resilient in the way implied by this principle.
In Design principle, SOLID – the "O" in "SOLID" stands for the open/closed principle.
Open Closed principle is a design principle which says that a class, modules and functions should be open for extension but closed for modification.
This principle states that the design and writing of the code should be done in a way that new functionality should be added with minimum changes in the existing code (tested code). The design should be done in a way to allow the adding of new functionality as new classes, keeping as much as possible existing code unchanged.
Benefit of Open Closed Design Principle:
Application will be more robust because we are not changing already tested class.
Flexible because we can easily accommodate new requirements.
Easy to test and less error prone.
My blog post on this:
http://javaexplorer03.blogspot.in/2016/12/open-closed-design-principle.html