I am pretty aware of the benefits of interfaces and how it helps aggregate common functionality of similar types of objects. However I believe people have taken this 'always program to an interface' a bit too far.
a) People starting off by ALWAYS defining an interface and then implementing it in a class even if that interface is too specific to be implemented by any other class. - Am I the only one who thinks that this serves no useful purpose?
b) Forcing all 'related' interfaces to derive for a common (useless) interface because it is now 'extendable' - What?
c) What do you do in scenarios where two or more objects seem related but it is very difficult to define common interface methods because of its underlying differences?
Lets say for example, an interface named IConnection with a Connect() method. (this is how most examples trivialize interfaces). The problem is, different type of classes that implement the IConnection interface might require different data for establishing the connection, some might require a user name and password, some might require some kind of special connection key, some might require nothing at all. The Connect method as a contract is perfectly valid as each class will need some way of establishing a connection but the data they need is different.
Is an interface required in this case? If it is, how do you define the Connect method? If not, how do you prove that your concrete classes are still 'extendable'?
Sorry for the long rant, this has been bugging me for quite some time now. Most people after reading the famous design patterns book try to implement every possible pattern in everything they do without bothering to figure out whether it helps. I believe the pattern should be brought into play when you are faced with a problem not just for the heck of it.
In your IConnection example you're basically describing an abstract Connect() method, since each class will have to implement its own version. Usually (always?) abstract methods can only be defined with the same parameters, so Connect(username, password) and Connect(key) couldn't be implementations of the same Connect() method from an interface.
Now, at this point, you could define it as IConnection::Connect(SomeConnectionData) and derive UsernamePasswordConnectionData and KeyConnectionData, etc., etc. from that SomeConnectionData class but all this would be so hard to explain and implement that its pretty good clue that interfaces and inheritance aren't helping the situation.
If it makes programming it and using it harder, don't do it. If something is made "extendable" by becoming too complex to understand, no will extend it anyway. It's perfectly okay to define a bunch of classes, each with their own Connect() methods just as a convention.
Related
From a design point of view, can I say that Interfaces are used to produce flexible code open for future easy maintenance. Referring to the case study, am I right to say:
Interface in this example is used because both Professor and HeadofDept class have the power to employ people. Assuming that we might add other people who might be given the right to employ people in the near future.
Thanks for your attention.
Interface will allow your code to call methods like employPeople() on the base type i.e EmployerProfessor. So you pass around EmployerProfessor objects and code need not know what the exact implementation is, it just knows that it can call employPeople(). So it allows for dynamic dispatch of method calls. Using some compiler implementation (vtable etc) it will call the correct method for you.
Interfaces are not always so flexible, its difficult to go and just change an interface since current code in the wild may be affected. An interface provides a contract, it tells the class implementing it, that you must provide the following methods.
Trying to code to an interface so that unit testing and design are better. Some things that I am coding doesn't seem to have any other implementation other than the obvious one. Is there a naming convention for this?
If you've only got one implementation, why not name your interface after it? You can always refactor the name later, if a second implementation comes along.
Most of the time, we do name our interfaces after the implementation that inspired them. If we then find that we get a second implementation of that interface, we'll either rename the original implementation to be more specific or rename the interface to be more general.
Maybe its because I've been coding around two semesters now, but the major stumbling block that I'm having at this point is converting the professor's project description and requirements to actual code. Since I'm currently in Algorithms 101, I basically do a bottom-up process, starting with a blank whiteboard and draw out the object and method interactions, then translate that into classes and code.
But now the prof has tossed interfaces and abstract classes into the mix. Intellectually, I can recognize how they work, but am stubbing my toes figuring out how to use these new tools with the current project (simulating a web server).
In my professors own words, mapping the abstract description to Java code is the real trick. So what steps are best used to go from English (or whatever your language is) to computer code? How do you decide where and when to create an interface, or use an abstract class?
So what steps are best used to go from English (or whatever your language is) to computer code?
Experience is what teaches you how to do this. If it's not coming naturally yet (and don't feel bad if it doesn't, because it takes a long time!), there are some questions you can ask yourself:
What are the main concepts of the system? How are they related to each other? If I was describing this to someone else, what words and phrases would I use? These thoughts will help you decide what classes are useful to think about.
What sorts of behaviors do these things have? Are there natural dependencies between them? (For example, a LineItem isn't relevant or meaningful without the context of an Order, nor is an Engine much use without a Car.) How do the behaviors affect the state of the other objects? Do they communicate with each other, and if so, in what way? These thoughts will help you develop the public interfaces of your classes.
That's just the tip of the iceberg, of course. For more about this thought process in general, see Eric Evans's excellent book, Domain-Driven Design.
How do you decide where and when to create an interface, or use an abstract class?
There's no hard and fast prescriptions; again, experience is the best guide here. That said, there's certainly some rules of thumb you can follow:
If several unrelated or significantly different object types all provide the same kind of functionality, use an interface. For example, if the Steerable interface has a Steer(Vector bearing) method, there may be lots of different things that can be steered: Boats, Airplanes, CargoShips, Cars, et cetera. These are completely unrelated things. But they all share the common interface of being able to be steered.
In general, try to favor an interface instead of an abstract base class. This way you can define a single implementation which implements N interfaces. In the case of Java, you can only have one abstract base class, so you're locked into a particular inheritance hierarchy once you say that a class inherits from another one.
Whenever you don't need implementation from a base class, definitely favor an interface over an abstract base class. This would also be handy if you're operating in a language where inheritance doesn't apply. For example, in C#, you can't have a struct inherit from a base class.
In general...
Read a lot of other people's code. Open source projects are great for that. Respect their licenses though.
You'll never get it perfect. It's an iterative process. Don't be discouraged if you don't get it right.
Practice. Practice. Practice.
Research often. Keep tackling more and more challenging projects / designs. Even if there are easy ones around.
There is no magic bullet, or algorithm for good design.
Nowadays I jump in with a design I believe is decent and work from that.
When the time is right I'll implement understanding the result will have to refactored ( rewritten ) sooner rather than later.
Give this project your best shot, keep an eye out for your mistakes and how things should've been done after you get back your results.
Keep doing this, and you'll be fine.
What you should really do is code from the top-down, not from the bottom-up. Write your main function as clearly and concisely as you can using APIs that you have not yet created as if they already existed. Then, you can implement those APIs in similar fashion, until you have functions that are only a few lines long. If you code from the bottom-up, you will likely create a whole lot of stuff that you don't actually need.
In terms of when to create an interface... pretty much everything should be an interface. When you use APIs that don't yet exist, assume that every concrete class is an implementation of some interface, and use a declared type that is indicative of that interface. Your inheritance should be done solely with interfaces. Only create concrete classes at the very bottom when you are providing an implementation. I would suggest avoiding abstract classes and just using delegation, although abstract classes are also reasonable when two different implementations differ only slightly and have several functions that have a common implementation. For example, if your interface allows one to iterate over elements and also provides a sum function, the sum function is a trivial to implement in terms of the iteration function, so that would be a reasonable use of an abstract class. An alternative would be to use the decorator pattern in that case.
You might also find the Google Techtalk "How to Design a Good API and Why it Matters" to be helpful in this regard. You might also be interested in reading some of my own software design observations.
Also, for the coming future, you can keep in pipeline to read the basics on domain driven design to align yourself to the real world scenarios - it gives a solid foundation for requirements mapping to the real classes.
At my old C++ job, we always took great care in encapsulating member variables, and only exposing them as properties when absolutely necessary. We'd have really specific constructors that made sure you fully constructed the object before using it.
These days, with ORM frameworks, dependency-injection, serialization, etc., it seems like you're better off just relying on the default constructor and exposing everything about your class in properties, so that you can inject things, or build and populate objects more dynamically.
In C#, it's been taken one step further with Object initializers, which give you the ability to basically define your own constructor. (I know object initializers are not really custom constructors, but I hope you get my point.)
Are there any general concerns with this direction? It seems like encapsulation is starting to become less important in favor of convenience.
EDIT: I know you can still carefully encapsulate members, but I just feel like when you're trying to crank out some classes, you either have to sit and carefully think about how to encapsulate each member, or just expose it as a property, and worry about how it is initialized later. It just seems like the easiest approach these days is to expose things as properties, and not be so careful. Maybe I'm just flat wrong, but that's just been my experience, espeically with the new C# language features.
I disagree with your conclusion. There are many good ways of encapsulating in c# with all the above mentioned technologies, as to maintain good software coding practices. I would also say that it depends on whose technology demo you're looking at, but in the end it comes down to reducing the state-space of your objects so that you can make sure they hold their invariants at all times.
Take object relational frameworks; most of them allow you to specify how they are going to hydrate the entities; NHibernate for example allows you so say access="property" or access="field.camelcase" and similar. This allows you to encapsulate your properties.
Dependency injection works on the other types you have, mostly those which are not entities, even though you can combine AOP+ORM+IOC in some very nice ways to improve the state of these things. IoC is often used from layers above your domain entities if you're building a data-driven application, which I guess you are, since you're talking about ORMs.
They ("they" being application and domain services and other intrinsic classes to the program) expose their dependencies but in fact can be encapsulated and tested in even better isolation than previously since the paradigms of design-by-contract/design-by-interface which you often use when mocking dependencies in mock-based testing (in conjunction with IoC), will move you towards class-as-component "semantics". I mean: every class, when built using the above, will be better encapsulated.
Updated for urig: This holds true for both exposing concrete dependencies and exposing interfaces. First about interfaces: What I was hinting at above was that services and other applications classes which have dependencies, can with OOP depend on contracts/interfaces rather than specific implementations. In C/C++ and older languages there wasn't the interface and abstract classes can only go so far. Interfaces allow you to tie different runtime instances to the same interface without having to worry about leaking internal state which is what you're trying to get away from when abstracting and encapsulating. With abstract classes you can still provide a class implementation, just that you can't instantiate it, but inheritors still need to know about the invariants in your implementation and that can mess up state.
Secondly, about concrete classes as properties: you have to be wary about what types of types ;) you expose as properties. Say you have a List in your instance; then don't expose IList as the property; this will probably leak and you can't guarantee that consumers of the interface don't add things or remove things which you depend on; instead expose something like IEnumerable and return a copy of the List, or even better, do it as a method:
public IEnumerable MyCollection { get { return _List.Enum(); } } and you can be 100% certain to get both the performance and the encapsulation. Noone can add or remove to that IEnumerable and you still don't have to perform a costly array copy. The corresponding helper method:
static class Ext {
public static IEnumerable<T> Enum<T>(this IEnumerable<T> inner) {
foreach (var item in inner) yield return item;
}
}
So while you can't get 100% encapsulation in say creating overloaded equals operators/method you can get close with your public interfaces.
You can also use the new features of .Net 4.0 built on Spec# to verify the contracts I talked about above.
Serialization will always be there and has been for a long time. Previously, before the internet-area it was used for saving your object graph to disk for later retrieval, now it's used in web services, in copy-semantics and when passing data to e.g. a browser. This doesn't necessarily break encapsulation if you put a few [NonSerialized] attributes or the equivalents on the correct fields.
Object initializers aren't the same as constructors, they are just a way of collapsing a few lines of code. Values/instances in the {} will not be assigned until all of your constructors have run, so in principle it's just the same as not using object initializers.
I guess, what you have to watch out for is deviating from the good principles you've learnt from your previous job and make sure you are keeping your domain objects filled with business logic encapsulated behind good interfaces and ditto for your service-layer.
Private members are still incredibly important. Controlling access to internal object data is always good, and shouldn't be ignored.
Many times private methods I've found to be overkill. Most of the time, if the work you're doing is important enough to break out, you can refactor it in such a way that either a) the private method is trivial, or b) is an integral part of other functions.
In addition, with unit testing, having many methods private makes it very hard to unit test. There are ways around that (making test objects friends, etc), but add difficulties.
I wouldn't discount private methods entirely though. Any time there's important, internal algorithms that really make no sense outside of the class there's no reason to expose those methods.
I think that encapsulation is still important, it helps more in libraries than anything imho. You can create a library that does X, but you don't need everyone to know how X was created. And if you wanted to create it more specifically to obfuscate the way you create X. The way I learned about encapsulation, I remember also that you should always define your variables as private to protect them from a data attack. To protect against a hacker breaking your code and accessing variables that they are not supposed to use.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Why are interfaces useful?
Actually, I have a [small] idea of why interfaces are useful/necessary but...
What are [interesting or realistic] applications of interfaces?
Interfaces are interesting because you can allow 2 classes to implement the same methods. Lets look at an example.
Say I have a base class called Animal. All animals breathe, and communicate. Now lets say I have 3 classes, called Dolphin, Human, and Tiger. All of theses animals breathe and communicate. But I want to implement a walking method for the Human and Tiger. Dolphins cant walk. So I inherit the IWalk method for the latter two, and when I compile the class, I HAVE to implement the methods specified in the interface, or it won't compile. It's a contract saying, "If I want to implement this class, I have to implement these methods."
One use that I have for interfaces is to help with unit testing framework classes that are hard to mock. I will create an interface that works basically the same as the framework class and a wrapper class that implements the interface. The constructor of the wrapper class takes an instance of the framework class as an argument. The wrapper delegates the interface functionality it supports to the framework class, but I implement to my interface instead of the framework. Using the interface makes it easy for me to mock out the wrapper class's functionality in my unit tests -- either using a mocking framework or by providing a fake class that also implements the interface and supplying it via dependency injection to any classes that would normally rely on the framework class.
They allow polymorphism without some of the bad sides of inheritance.
What do I mean by bad sides of inheritance?
Code and Data inherited down a long chain (making it less obvious).
Inherited members that are over-ridden somewhere in the inheritance tree.
How can you use polymorphism?
To avoid repeating yourself. Create functions, switches, or conditionals which use the interface instead of the objects that implement the interface.
Java Specific
In Java, it often makes sense to use interfaces as a way to get multiple-inheritance.
This makes sense if something naturally fits into two categories and you have separate behavior expected for both of them.
Some Java Examples from the Web
http://home.cogeco.ca/~ve3ll/jatutor5.htm
http://java.freehep.org/lib/freehep/doc/root/index.html
http://www.codeguru.com/java/tij/tij0080.shtml
An interface (or an abstract class) is a contract you pass with the compiler. This contract says :
-- Well, compiler, make sure that all the classes that will implement this will provide at least everything that is defined in this interface !
With this insurance, you can then write methods that manipulate objects of any class implementing this interface :
void myGenericMethod( IAnInterface genericObject )
myGenericMethod method can use any member of the interface IAnInterface. It will never throw a runtime error (any missing member will have been caught by the compiler).
Utility : to give some common behavior to different objects. You may want for example to be able to call a method named GetID on any of your objects, being it a BankAccount, a ComputerCluster or an AirplaneTrip.
You will find a lot of useful interface usages in most design patterns. MSDN provides some hints about when you should use an interface here : http://msdn.microsoft.com/en-us/library/27db6csx.aspx
As tvanfosson mentioned, there very useful for mocking, also if you writing a library that depends on outside configuration you can make an IFooProvider and have the calling program implement it.
I assume you mean "interface" in the programming language sense rather than in the other senses, e.g. "User Interface".
An interface in languages like Java or C# serves two purposes. The first is to provide a contract for a type to implement; a suite of method names and signatures that the type provides to other types that use it. The second is to provide polymorphism upon that interface for the type. For example, if I have a type that implements the IFoo interface, I can pass an instance of that type to another class where the other class needs only know about the IFoo interface rather than every detail of my class that implements IFoo.
Interfaces are useful when you want to allow interoperability between two classes that do not share a common class hierarchy.
A good example of this is java.lang.CharSequence. Lots of other things can be abstractly treated as strings, but it wouldn't be correct to subclass String to do so. In fact String is final so it couldn't be done anyway.
Some time around JDK 1.4 (I beleive?) the CharSequence interface was introduced. Now String, StringBuffer, CharBuffer and lots of other existing classes in the JDK implement it. With that, new methods could be added to other APIs which accept CharSequence, allowing them to abstractly handle all of these in a unified way.
You can also implement this interface yourself and use it the same way. It's far more flexible to implement a common interface than try and force things to extend from a specific base class (or sometimes it's impossible).
I prefer to regard an interface as a description of a role to be fulfilled by each instance of an implementing class, independent of any implementation inheritance hierarchy.
By way of analogy, you can describe a "screen pass" football play in terms of how certain positions on the team interact. That description, in terms of position (or role or interface) is independent of which player happens to be playing the position at a given time. It's also independent of whether the team happens to have some talented players who can play more than one position.
The advantage of interface-oriented thinking is that it puts the focus on the role that an object fulfills in a given interaction with other objects, without concern for any other roles the object may play in other kinds of interactions. It also allows testing to focus on scenarios that are relevant to a role (and to mock or fake roles in a test scenario).