Related
I have seen this mentioned a few times and I am not clear on what it means. When and why would you do this?
I know what interfaces do, but the fact I am not clear on this makes me think I am missing out on using them correctly.
Is it just so if you were to do:
IInterface classRef = new ObjectWhatever()
You could use any class that implements IInterface? When would you need to do that? The only thing I can think of is if you have a method and you are unsure of what object will be passed except for it implementing IInterface. I cannot think how often you would need to do that.
Also, how could you write a method that takes in an object that implements an interface? Is that possible?
There are some wonderful answers on here to this questions that get into all sorts of great detail about interfaces and loosely coupling code, inversion of control and so on. There are some fairly heady discussions, so I'd like to take the opportunity to break things down a bit for understanding why an interface is useful.
When I first started getting exposed to interfaces, I too was confused about their relevance. I didn't understand why you needed them. If we're using a language like Java or C#, we already have inheritance and I viewed interfaces as a weaker form of inheritance and thought, "why bother?" In a sense I was right, you can think of interfaces as sort of a weak form of inheritance, but beyond that I finally understood their use as a language construct by thinking of them as a means of classifying common traits or behaviors that were exhibited by potentially many non-related classes of objects.
For example -- say you have a SIM game and have the following classes:
class HouseFly inherits Insect {
void FlyAroundYourHead(){}
void LandOnThings(){}
}
class Telemarketer inherits Person {
void CallDuringDinner(){}
void ContinueTalkingWhenYouSayNo(){}
}
Clearly, these two objects have nothing in common in terms of direct inheritance. But, you could say they are both annoying.
Let's say our game needs to have some sort of random thing that annoys the game player when they eat dinner. This could be a HouseFly or a Telemarketer or both -- but how do you allow for both with a single function? And how do you ask each different type of object to "do their annoying thing" in the same way?
The key to realize is that both a Telemarketer and HouseFly share a common loosely interpreted behavior even though they are nothing alike in terms of modeling them. So, let's make an interface that both can implement:
interface IPest {
void BeAnnoying();
}
class HouseFly inherits Insect implements IPest {
void FlyAroundYourHead(){}
void LandOnThings(){}
void BeAnnoying() {
FlyAroundYourHead();
LandOnThings();
}
}
class Telemarketer inherits Person implements IPest {
void CallDuringDinner(){}
void ContinueTalkingWhenYouSayNo(){}
void BeAnnoying() {
CallDuringDinner();
ContinueTalkingWhenYouSayNo();
}
}
We now have two classes that can each be annoying in their own way. And they do not need to derive from the same base class and share common inherent characteristics -- they simply need to satisfy the contract of IPest -- that contract is simple. You just have to BeAnnoying. In this regard, we can model the following:
class DiningRoom {
DiningRoom(Person[] diningPeople, IPest[] pests) { ... }
void ServeDinner() {
when diningPeople are eating,
foreach pest in pests
pest.BeAnnoying();
}
}
Here we have a dining room that accepts a number of diners and a number of pests -- note the use of the interface. This means that in our little world, a member of the pests array could actually be a Telemarketer object or a HouseFly object.
The ServeDinner method is called when dinner is served and our people in the dining room are supposed to eat. In our little game, that's when our pests do their work -- each pest is instructed to be annoying by way of the IPest interface. In this way, we can easily have both Telemarketers and HouseFlys be annoying in each of their own ways -- we care only that we have something in the DiningRoom object that is a pest, we don't really care what it is and they could have nothing in common with other.
This very contrived pseudo-code example (that dragged on a lot longer than I anticipated) is simply meant to illustrate the kind of thing that finally turned the light on for me in terms of when we might use an interface. I apologize in advance for the silliness of the example, but hope that it helps in your understanding. And, to be sure, the other posted answers you've received here really cover the gamut of the use of interfaces today in design patterns and development methodologies.
The specific example I used to give to students is that they should write
List myList = new ArrayList(); // programming to the List interface
instead of
ArrayList myList = new ArrayList(); // this is bad
These look exactly the same in a short program, but if you go on to use myList 100 times in your program you can start to see a difference. The first declaration ensures that you only call methods on myList that are defined by the List interface (so no ArrayList specific methods). If you've programmed to the interface this way, later on you can decide that you really need
List myList = new TreeList();
and you only have to change your code in that one spot. You already know that the rest of your code doesn't do anything that will be broken by changing the implementation because you programmed to the interface.
The benefits are even more obvious (I think) when you're talking about method parameters and return values. Take this for example:
public ArrayList doSomething(HashMap map);
That method declaration ties you to two concrete implementations (ArrayList and HashMap). As soon as that method is called from other code, any changes to those types probably mean you're going to have to change the calling code as well. It would be better to program to the interfaces.
public List doSomething(Map map);
Now it doesn't matter what kind of List you return, or what kind of Map is passed in as a parameter. Changes that you make inside the doSomething method won't force you to change the calling code.
Programming to an interface is saying, "I need this functionality and I don't care where it comes from."
Consider (in Java), the List interface versus the ArrayList and LinkedList concrete classes. If all I care about is that I have a data structure containing multiple data items that I should access via iteration, I'd pick a List (and that's 99% of the time). If I know that I need constant-time insert/delete from either end of the list, I might pick the LinkedList concrete implementation (or more likely, use the Queue interface). If I know I need random access by index, I'd pick the ArrayList concrete class.
Programming to an interface has absolutely nothing to do with abstract interfaces like we see in Java or .NET. It isn't even an OOP concept.
What it means is don't go messing around with the internals of an object or data structure. Use the Abstract Program Interface, or API, to interact with your data. In Java or C# that means using public properties and methods instead of raw field access. For C that means using functions instead of raw pointers.
EDIT: And with databases it means using views and stored procedures instead of direct table access.
Using interfaces is a key factor in making your code easily testable in addition to removing unnecessary couplings between your classes. By creating an interface that defines the operations on your class, you allow classes that want to use that functionality the ability to use it without depending on your implementing class directly. If later on you decide to change and use a different implementation, you need only change the part of the code where the implementation is instantiated. The rest of the code need not change because it depends on the interface, not the implementing class.
This is very useful in creating unit tests. In the class under test you have it depend on the interface and inject an instance of the interface into the class (or a factory that allows it to build instances of the interface as needed) via the constructor or a property settor. The class uses the provided (or created) interface in its methods. When you go to write your tests, you can mock or fake the interface and provide an interface that responds with data configured in your unit test. You can do this because your class under test deals only with the interface, not your concrete implementation. Any class implementing the interface, including your mock or fake class, will do.
EDIT: Below is a link to an article where Erich Gamma discusses his quote, "Program to an interface, not an implementation."
http://www.artima.com/lejava/articles/designprinciples.html
You should look into Inversion of Control:
Martin Fowler: Inversion of Control Containers and the Dependency Injection pattern
Wikipedia: Inversion of Control
In such a scenario, you wouldn't write this:
IInterface classRef = new ObjectWhatever();
You would write something like this:
IInterface classRef = container.Resolve<IInterface>();
This would go into a rule-based setup in the container object, and construct the actual object for you, which could be ObjectWhatever. The important thing is that you could replace this rule with something that used another type of object altogether, and your code would still work.
If we leave IoC off the table, you can write code that knows that it can talk to an object that does something specific, but not which type of object or how it does it.
This would come in handy when passing parameters.
As for your parenthesized question "Also, how could you write a method that takes in an object that implements an Interface? Is that possible?", in C# you would simply use the interface type for the parameter type, like this:
public void DoSomethingToAnObject(IInterface whatever) { ... }
This plugs right into the "talk to an object that does something specific." The method defined above knows what to expect from the object, that it implements everything in IInterface, but it doesn't care which type of object it is, only that it adheres to the contract, which is what an interface is.
For instance, you're probably familiar with calculators and have probably used quite a few in your days, but most of the time they're all different. You, on the other hand, knows how a standard calculator should work, so you're able to use them all, even if you can't use the specific features that each calculator has that none of the other has.
This is the beauty of interfaces. You can write a piece of code, that knows that it will get objects passed to it that it can expect certain behavior from. It doesn't care one hoot what kind of object it is, only that it supports the behavior needed.
Let me give you a concrete example.
We have a custom-built translation system for windows forms. This system loops through controls on a form and translate text in each. The system knows how to handle basic controls, like the-type-of-control-that-has-a-Text-property, and similar basic stuff, but for anything basic, it falls short.
Now, since controls inherit from pre-defined classes that we have no control over, we could do one of three things:
Build support for our translation system to detect specifically which type of control it is working with, and translate the correct bits (maintenance nightmare)
Build support into base classes (impossible, since all the controls inherit from different pre-defined classes)
Add interface support
So we did nr. 3. All our controls implement ILocalizable, which is an interface that gives us one method, the ability to translate "itself" into a container of translation text/rules. As such, the form doesn't need to know which kind of control it has found, only that it implements the specific interface, and knows that there is a method where it can call to localize the control.
Code to the Interface Not the Implementation has NOTHING to do with Java, nor its Interface construct.
This concept was brought to prominence in the Patterns / Gang of Four books but was most probably around well before that. The concept certainly existed well before Java ever existed.
The Java Interface construct was created to aid in this idea (among other things), and people have become too focused on the construct as the centre of the meaning rather than the original intent. However, it is the reason we have public and private methods and attributes in Java, C++, C#, etc.
It means just interact with an object or system's public interface. Don't worry or even anticipate how it does what it does internally. Don't worry about how it is implemented. In object-oriented code, it is why we have public vs. private methods/attributes. We are intended to use the public methods because the private methods are there only for use internally, within the class. They make up the implementation of the class and can be changed as required without changing the public interface. Assume that regarding functionality, a method on a class will perform the same operation with the same expected result every time you call it with the same parameters. It allows the author to change how the class works, its implementation, without breaking how people interact with it.
And you can program to the interface, not the implementation without ever using an Interface construct. You can program to the interface not the implementation in C++, which does not have an Interface construct. You can integrate two massive enterprise systems much more robustly as long as they interact through public interfaces (contracts) rather than calling methods on objects internal to the systems. The interfaces are expected to always react the same expected way given the same input parameters; if implemented to the interface and not the implementation. The concept works in many places.
Shake the thought that Java Interfaces have anything what-so-ever to do with the concept of 'Program to the Interface, Not the Implementation'. They can help apply the concept, but they are not the concept.
It sounds like you understand how interfaces work but are unsure of when to use them and what advantages they offer. Here are a few examples of when an interface would make sense:
// if I want to add search capabilities to my application and support multiple search
// engines such as Google, Yahoo, Live, etc.
interface ISearchProvider
{
string Search(string keywords);
}
then I could create GoogleSearchProvider, YahooSearchProvider, LiveSearchProvider, etc.
// if I want to support multiple downloads using different protocols
// HTTP, HTTPS, FTP, FTPS, etc.
interface IUrlDownload
{
void Download(string url)
}
// how about an image loader for different kinds of images JPG, GIF, PNG, etc.
interface IImageLoader
{
Bitmap LoadImage(string filename)
}
then create JpegImageLoader, GifImageLoader, PngImageLoader, etc.
Most add-ins and plugin systems work off interfaces.
Another popular use is for the Repository pattern. Say I want to load a list of zip codes from different sources
interface IZipCodeRepository
{
IList<ZipCode> GetZipCodes(string state);
}
then I could create an XMLZipCodeRepository, SQLZipCodeRepository, CSVZipCodeRepository, etc. For my web applications, I often create XML repositories early on so I can get something up and running before the SQL Database is ready. Once the database is ready I write an SQLRepository to replace the XML version. The rest of my code remains unchanged since it runs solely off of interfaces.
Methods can accept interfaces such as:
PrintZipCodes(IZipCodeRepository zipCodeRepository, string state)
{
foreach (ZipCode zipCode in zipCodeRepository.GetZipCodes(state))
{
Console.WriteLine(zipCode.ToString());
}
}
It makes your code a lot more extensible and easier to maintain when you have sets of similar classes. I am a junior programmer, so I am no expert, but I just finished a project that required something similar.
I work on client side software that talks to a server running a medical device. We are developing a new version of this device that has some new components that the customer must configure at times. There are two types of new components, and they are different, but they are also very similar. Basically, I had to create two config forms, two lists classes, two of everything.
I decided that it would be best to create an abstract base class for each control type that would hold almost all of the real logic, and then derived types to take care of the differences between the two components. However, the base classes would not have been able to perform operations on these components if I had to worry about types all of the time (well, they could have, but there would have been an "if" statement or switch in every method).
I defined a simple interface for these components and all of the base classes talk to this interface. Now when I change something, it pretty much 'just works' everywhere and I have no code duplication.
A lot of explanation out there, but to make it even more simpler. Take for instance a List. One can implement a list with as:
An internal array
A linked list
Other implementations
By building to an interface, say a List. You only code as to definition of List or what List means in reality.
You could use any type of implementation internally say an array implementation. But suppose you wish to change the implementation for some reason say a bug or performance. Then you just have to change the declaration List<String> ls = new ArrayList<String>() to List<String> ls = new LinkedList<String>().
Nowhere else in code, will you have to change anything else; Because everything else was built on the definition of List.
If you program in Java, JDBC is a good example. JDBC defines a set of interfaces but says nothing about the implementation. Your applications can be written against this set of interfaces. In theory, you pick some JDBC driver and your application would just work. If you discover there's a faster or "better" or cheaper JDBC driver or for whatever reason, you can again in theory re-configure your property file, and without having to make any change in your application, your application would still work.
I am a late comer to this question, but I want to mention here that the line "Program to an interface, not an implementation" had some good discussion in the GoF (Gang of Four) Design Patterns book.
It stated, on p. 18:
Program to an interface, not an implementation
Don't declare variables to be instances of particular concrete classes. Instead, commit only to an interface defined by an abstract class. You will find this to be a common theme of the design patterns in this book.
and above that, it began with:
There are two benefits to manipulating objects solely in terms of the interface defined by abstract classes:
Clients remain unaware of the specific types of objects they use, as long as the objects adhere to the interface that clients expect.
Clients remain unaware of the classes that implement these objects. Clients only know about the abstract class(es) defining the interface.
So in other words, don't write it your classes so that it has a quack() method for ducks, and then a bark() method for dogs, because they are too specific for a particular implementation of a class (or subclass). Instead, write the method using names that are general enough to be used in the base class, such as giveSound() or move(), so that they can be used for ducks, dogs, or even cars, and then the client of your classes can just say .giveSound() rather than thinking about whether to use quack() or bark() or even determine the type before issuing the correct message to be sent to the object.
Programming to Interfaces is awesome, it promotes loose coupling. As #lassevk mentioned, Inversion of Control is a great use of this.
In addition, look into SOLID principals. here is a video series
It goes through a hard coded (strongly coupled example) then looks at interfaces, finally progressing to a IoC/DI tool (NInject)
To add to the existing posts, sometimes coding to interfaces helps on large projects when developers work on separate components simultaneously. All you need is to define interfaces upfront and write code to them while other developers write code to the interface you are implementing.
It can be advantageous to program to interfaces, even when we are not depending on abstractions.
Programming to interfaces forces us to use a contextually appropriate subset of an object. That helps because it:
prevents us from doing contextually inappropriate things, and
lets us safely change the implementation in the future.
For example, consider a Person class that implements the Friend and the Employee interface.
class Person implements AbstractEmployee, AbstractFriend {
}
In the context of the person's birthday, we program to the Friend interface, to prevent treating the person like an Employee.
function party() {
const friend: Friend = new Person("Kathryn");
friend.HaveFun();
}
In the context of the person's work, we program to the Employee interface, to prevent blurring workplace boundaries.
function workplace() {
const employee: Employee = new Person("Kathryn");
employee.DoWork();
}
Great. We have behaved appropriately in different contexts, and our software is working well.
Far into the future, if our business changes to work with dogs, we can change the software fairly easily. First, we create a Dog class that implements both Friend and Employee. Then, we safely change new Person() to new Dog(). Even if both functions have thousands of lines of code, that simple edit will work because we know the following are true:
Function party uses only the Friend subset of Person.
Function workplace uses only the Employee subset of Person.
Class Dog implements both the Friend and Employee interfaces.
On the other hand, if either party or workplace were to have programmed against Person, there would be a risk of both having Person-specific code. Changing from Person to Dog would require us to comb through the code to extirpate any Person-specific code that Dog does not support.
The moral: programming to interfaces helps our code to behave appropriately and to be ready for change. It also prepares our code to depend on abstractions, which brings even more advantages.
If I'm writing a new class Swimmer to add the functionality swim() and need to use an object of class say Dog, and this Dog class implements interface Animal which declares swim().
At the top of the hierarchy (Animal), it's very abstract while at the bottom (Dog) it's very concrete. The way I think about "programming to interfaces" is that, as I write Swimmer class, I want to write my code against the interface that's as far up that hierarchy which in this case is an Animal object. An interface is free from implementation details and thus makes your code loosely-coupled.
The implementation details can be changed with time, however, it would not affect the remaining code since all you are interacting with is with the interface and not the implementation. You don't care what the implementation is like... all you know is that there will be a class that would implement the interface.
It is also good for Unit Testing, you can inject your own classes (that meet the requirements of the interface) into a class that depends on it
Short story: A postman is asked to go home after home and receive the covers contains (letters, documents, cheques, gift cards, application, love letter) with the address written on it to deliver.
Suppose there is no cover and ask the postman to go home after home and receive all the things and deliver to other people, the postman can get confused.
So better wrap it with cover (in our story it is the interface) then he will do his job fine.
Now the postman's job is to receive and deliver the covers only (he wouldn't bothered what is inside in the cover).
Create a type of interface not actual type, but implement it with actual type.
To create to interface means your components get Fit into the rest of code easily
I give you an example.
you have the AirPlane interface as below.
interface Airplane{
parkPlane();
servicePlane();
}
Suppose you have methods in your Controller class of Planes like
parkPlane(Airplane plane)
and
servicePlane(Airplane plane)
implemented in your program. It will not BREAK your code.
I mean, it need not to change as long as it accepts arguments as AirPlane.
Because it will accept any Airplane despite actual type, flyer, highflyr, fighter, etc.
Also, in a collection:
List<Airplane> plane; // Will take all your planes.
The following example will clear your understanding.
You have a fighter plane that implements it, so
public class Fighter implements Airplane {
public void parkPlane(){
// Specific implementations for fighter plane to park
}
public void servicePlane(){
// Specific implementatoins for fighter plane to service.
}
}
The same thing for HighFlyer and other clasess:
public class HighFlyer implements Airplane {
public void parkPlane(){
// Specific implementations for HighFlyer plane to park
}
public void servicePlane(){
// specific implementatoins for HighFlyer plane to service.
}
}
Now think your controller classes using AirPlane several times,
Suppose your Controller class is ControlPlane like below,
public Class ControlPlane{
AirPlane plane;
// so much method with AirPlane reference are used here...
}
Here magic comes as you may make your new AirPlane type instances as many as you want and you are not changing the code of ControlPlane class.
You can add an instance...
JumboJetPlane // implementing AirPlane interface.
AirBus // implementing AirPlane interface.
You may remove instances of previously created types too.
So, just to get this right, the advantage of a interface is that I can separate the calling of a method from any particular class. Instead creating a instance of the interface, where the implementation is given from whichever class I choose that implements that interface. Thus allowing me to have many classes, which have similar but slightly different functionality and in some cases (the cases related to the intention of the interface) not care which object it is.
For example, I could have a movement interface. A method which makes something 'move' and any object (Person, Car, Cat) that implements the movement interface could be passed in and told to move. Without the method every knowing the type of class it is.
Imagine you have a product called 'Zebra' that can be extended by plugins. It finds the plugins by searching for DLLs in some directory. It loads all those DLLs and uses reflection to find any classes that implement IZebraPlugin, and then calls the methods of that interface to communicate with the plugins.
This makes it completely independent of any specific plugin class - it doesn't care what the classes are. It only cares that they fulfill the interface specification.
Interfaces are a way of defining points of extensibility like this. Code that talks to an interface is more loosely coupled - in fact it is not coupled at all to any other specific code. It can inter-operate with plugins written years later by people who have never met the original developer.
You could instead use a base class with virtual functions - all plugins would be derived from the base class. But this is much more limiting because a class can only have one base class, whereas it can implement any number of interfaces.
C++ explanation.
Think of an interface as your classes public methods.
You then could create a template that 'depends' on these public methods in order to carry out it's own function (it makes function calls defined in the classes public interface). Lets say this template is a container, like a Vector class, and the interface it depends on is a search algorithm.
Any algorithm class that defines the functions/interface Vector makes calls to will satisfy the 'contract' (as someone explained in the original reply). The algorithms don't even need to be of the same base class; the only requirement is that the functions/methods that the Vector depends on (interface) is defined in your algorithm.
The point of all of this is that you could supply any different search algorithm/class just as long as it supplied the interface that Vector depends on (bubble search, sequential search, quick search).
You might also want to design other containers (lists, queues) that would harness the same search algorithm as Vector by having them fulfill the interface/contract that your search algorithms depends on.
This saves time (OOP principle 'code reuse') as you are able to write an algorithm once instead of again and again and again specific to every new object you create without over-complicating the issue with an overgrown inheritance tree.
As for 'missing out' on how things operate; big-time (at least in C++), as this is how most of the Standard TEMPLATE Library's framework operates.
Of course when using inheritance and abstract classes the methodology of programming to an interface changes; but the principle is the same, your public functions/methods are your classes interface.
This is a huge topic and one of the the cornerstone principles of Design Patterns.
In Java these concrete classes all implement the CharSequence interface:
CharBuffer, String, StringBuffer, StringBuilder
These concrete classes do not have a common parent class other than Object, so there is nothing that relates them, other than the fact they each have something to do with arrays of characters, representing such, or manipulating such. For instance, the characters of String cannot be changed once a String object is instantiated, whereas the characters of StringBuffer or StringBuilder can be edited.
Yet each one of these classes is capable of suitably implementing the CharSequence interface methods:
char charAt(int index)
int length()
CharSequence subSequence(int start, int end)
String toString()
In some cases, Java class library classes that used to accept String have been revised to now accept the CharSequence interface. So if you have an instance of StringBuilder, instead of extracting a String object (which means instantiating a new object instance), it can instead just pass the StringBuilder itself as it implements the CharSequence interface.
The Appendable interface that some classes implement has much the same kind of benefit for any situation where characters can be appended to an instance of the underlying concrete class object instance. All of these concrete classes implement the Appendable interface:
BufferedWriter, CharArrayWriter, CharBuffer, FileWriter, FilterWriter, LogStream, OutputStreamWriter, PipedWriter, PrintStream, PrintWriter, StringBuffer, StringBuilder, StringWriter, Writer
Previous answers focus on programming to an abstraction for the sake of extensibility and loose coupling. While these are very important points,
readability is equally important. Readability allows others (and your future self) to understand the code with minimal effort. This is why readability leverages abstractions.
An abstraction is, by definition, simpler than its implementation. An abstraction omits detail in order to convey the essence or purpose of a thing, but nothing more.
Because abstractions are simpler, I can fit a lot more of them in my head at one time, compared to implementations.
As a programmer (in any language) I walk around with a general idea of a List in my head at all times. In particular, a List allows random access, duplicate elements, and maintains order. When I see a declaration like this: List myList = new ArrayList() I think, cool, this is a List that's being used in the (basic) way that I understand; and I don't have to think any more about it.
On the other hand, I do not carry around the specific implementation details of ArrayList in my head. So when I see, ArrayList myList = new ArrayList(). I think, uh-oh, this ArrayList must be used in a way that isn't covered by the List interface. Now I have to track down all the usages of this ArrayList to understand why, because otherwise I won't be able to fully understand this code. It gets even more confusing when I discover that 100% of the usages of this ArrayList do conform to the List interface. Then I'm left wondering... was there some code relying on ArrayList implementation details that got deleted? Was the programmer who instantiated it just incompetent? Is this application locked into that specific implementation in some way at runtime? A way that I don't understand?
I'm now confused and uncertain about this application, and all we're talking about is a simple List. What if this was a complex business object ignoring its interface? Then my knowledge of the business domain is insufficient to understand the purpose of the code.
So even when I need a List strictly within a private method (nothing that would break other applications if it changed, and I could easily find/replace every usage in my IDE) it still benefits readability to program to an abstraction. Because abstractions are simpler than implementation details. You could say that programming to abstractions is one way of adhering to the KISS principle.
An interface is like a contract, where you want your implementation class to implement methods written in the contract (interface). Since Java does not provide multiple inheritance, "programming to interface" is a good way to achieve multiple inheritance.
If you have a class A that is already extending some other class B, but you want that class A to also follow certain guidelines or implement a certain contract, then you can do so by the "programming to interface" strategy.
Q: - ... "Could you use any class that implements an interface?"
A: - Yes.
Q: - ... "When would you need to do that?"
A: - Each time you need a class(es) that implements interface(s).
Note: We couldn't instantiate an interface not implemented by a class - True.
Why?
Because the interface has only method prototypes, not definitions (just functions names, not their logic)
AnIntf anInst = new Aclass();
// we could do this only if Aclass implements AnIntf.
// anInst will have Aclass reference.
Note: Now we could understand what happened if Bclass and Cclass implemented same Dintf.
Dintf bInst = new Bclass();
// now we could call all Dintf functions implemented (defined) in Bclass.
Dintf cInst = new Cclass();
// now we could call all Dintf functions implemented (defined) in Cclass.
What we have: Same interface prototypes (functions names in interface), and call different implementations.
Bibliography:
Prototypes - wikipedia
program to an interface is a term from the GOF book. i would not directly say it has to do with java interface but rather real interfaces. to achieve clean layer separation, you need to create some separation between systems for example: Let's say you had a concrete database you want to use, you would never "program to the database" , instead you would "program to the storage interface". Likewise you would never "program to a Web Service" but rather you would program to a "client interface". this is so you can easily swap things out.
i find these rules help me:
1. we use a java interface when we have multiple types of an object. if i just have single object, i dont see the point. if there are at least two concrete implementations of some idea, then i would use a java interface.
2. if as i stated above, you want to bring decoupling from an external system (storage system) to your own system (local DB) then also use a interface.
notice how there are two ways to consider when to use them.
Coding to an interface is a philosophy, rather than specific language constructs or design patterns - it instructs you what is the correct order of steps to follow in order to create better software systems (e.g. more resilient, more testable, more scalable, more extendible, and other nice traits).
What it actually means is:
===
Before jumping to implementations and coding (the HOW) - think of the WHAT:
What black boxes should make up your system,
What is each box' responsibility,
What are the ways each "client" (that is, one of those other boxes, 3rd party "boxes", or even humans) should communicate with it (the API of each box).
After you figure the above, go ahead and implement those boxes (the HOW).
Thinking first of what a box' is and what its API, leads the developer to distil the box' responsibility, and to mark for himself and future developers the difference between what is its exposed details ("API") and it's hidden details ("implementation details"), which is a very important differentiation to have.
One immediate and easily noticeable gain is the team can then change and improve implementations without affecting the general architecture. It also makes the system MUCH more testable (it goes well with the TDD approach).
===
Beyond the traits I've mentioned above, you also save A LOT OF TIME going this direction.
Micro Services and DDD, when done right, are great examples of "Coding to an interface", however the concept wins in every pattern from monoliths to "serverless", from BE to FE, from OOP to functional, etc....
I strongly recommend this approach for Software Engineering (and I basically believe it makes total sense in other fields as well).
Program to an interface allows to change implementation of contract defined by interface seamlessly. It allows loose coupling between contract and specific implementations.
IInterface classRef = new ObjectWhatever()
You could use any class that implements IInterface? When would you need to do that?
Have a look at this SE question for good example.
Why should the interface for a Java class be preferred?
does using an Interface hit performance?
if so how much?
Yes. It will have slight performance overhead in sub-seconds. But if your application has requirement to change the implementation of interface dynamically, don't worry about performance impact.
how can you avoid it without having to maintain two bits of code?
Don't try to avoid multiple implementations of interface if your application need them. In absence of tight coupling of interface with one specific implementation, you may have to deploy the patch to change one implementation to other implementation.
One good use case: Implementation of Strategy pattern:
Real World Example of the Strategy Pattern
"Program to interface" means don't provide hard code right the way, meaning your code should be extended without breaking the previous functionality. Just extensions, not editing the previous code.
Also I see a lot of good and explanatory answers here, so I want to give my point of view here, including some extra information what I noticed when using this method.
Unit testing
For the last two years, I have written a hobby project and I did not write unit tests for it. After writing about 50K lines I found out it would be really necessary to write unit tests.
I did not use interfaces (or very sparingly) ... and when I made my first unit test, I found out it was complicated. Why?
Because I had to make a lot of class instances, used for input as class variables and/or parameters. So the tests look more like integration tests (having to make a complete 'framework' of classes since all was tied together).
Fear of interfaces
So I decided to use interfaces. My fear was that I had to implement all functionality everywhere (in all used classes) multiple times. In some way this is true, however, by using inheritance it can be reduced a lot.
Combination of interfaces and inheritance
I found out the combination is very good to be used. I give a very simple example.
public interface IPricable
{
int Price { get; }
}
public interface ICar : IPricable
public abstract class Article
{
public int Price { get { return ... } }
}
public class Car : Article, ICar
{
// Price does not need to be defined here
}
This way copying code is not necessary, while still having the benefit of using a car as interface (ICar).
(Nothing serious in this question)
Ones a time I've read such an example of "bad application architecture":
There was a "rendering application" (browser, as far as I remember), so it was told, that having "render()" method in TagA, TagUL, TagDIV classes is really bad practice, because you'll have lots of "render-code" smeared all around. So (in this example), they adviced to have RenderA, RenderUL, RenderDIV classes that would implement rendering. And tag-objects would incapsulate those renderers.
I can't understand why that's a bad practice. In this case we'll have lot's of render code smeared around Render-* objects. And, finaly, why not to have Redner-singleton with lot's of overriden methods? That sounds, at least, cheaper.
What to read to understand it better?
Will the rendering for all of these different objects be the same? If so, then it should only be implemented once, most likely in a base class. This would be a better solution than a Singleton, which serves a completely different purpose: mainly to implement a resource (notice its a resource, not a method) that should only exist once.
If each implementation of render() will be different (which is most likely the case) then there is nothing wrong with them being implemented in separate objects, this is called polymorphism. What should probably be done though, is to have a class hierarchy in which the render() method is defined in the base class (most likely as abstract) and implemented in the derived classes. This effectively formalizes the interface, meaning that any class that inherits from said base class will have the render() method available and will have to implement it.
If you have parts of the render code that are common, and parts that are specific to the derived classes, instead of having to duplicate the common parts in all the derived class implementations, you can use a Template Method pattern, whereby the base class method does the common parts, and orchestrates calling the derived class implementation(s). Here is a pseudo-code example in C++
class TagBase {
public:
void render() {
// do some common stuff here
doRender();
// do some more common stuff here
}
virtual void doRender() = 0;
....
};
class TagA : public TagBase {
public:
virtual void doRender() {
// do your specific stuff here
}
};
Here are a few good books:
Design Patterns, Gang of Four
Head First Design Patterns
Head First Object Oriented Analysis and Design
I can't understand why that's a bad practice.
It might be bad practice if it's not a Tag's responsibility to render itself - see Single Responsibility Principle.
For instance, if the Tag class already includes HTML parsing behavior and you add rendering to it, it will have 2 responsibilities, 2 reasons to change and possibly to break. Due to their collocation, parsing will be tightly coupled to rendering, which brings a number of issues :
You can't change or add a variant to one of the responsibilities independently from the other - for instance adding mobile browser rendering in addition to desktop browser rendering will require writing another class where the parsing behavior is repeated. Smaller classes with more focused responsibilities means more moving parts and added modularity.
The more responsibilities a class embeds, the more bugs and side effects are likely to appear accidentally when you make changes to it. In many situations it's difficult to tell which of the 2 responsibilities caused the bug.
You have to rebuild, retest and redeploy all the responsibilities included in a class even if you only make changes to one of them.
It's also more difficult to debug one of the responsibilities when the other ones can interfere with it.
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.
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.
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