I work at a company where some require justification for the use of an Interface in our code (Visual Studio C# 3.5).
I would like to ask for an Iron Clad reasoning that interfaces are required for. (My goal is to PROVE that interfaces are a normal part of programming.)
I don't need convincing, I just need a good argument to use in the convincing of others.
The kind of argument I am looking for is fact based, not comparison based (ie "because the .NET library uses them" is comparison based.)
The argument against them is thus: If a class is properly setup (with its public and private members) then an interface is just extra overhead because those that use the class are restricted to public members. If you need to have an interface that is implemented by more than 1 class then just setup inheritance/polymorphism.
Code decoupling. By programming to interfaces you decouple the code using the interface from the code implementing the interface. This allows you to change the implementation without having to refactor all of the code using it. This works in conjunction with inheritance/polymorphism, allowing you to use any of a number of possible implementations interchangeably.
Mocking and unit testing. Mocking frameworks are most easily used when the methods are virtual, which you get by default with interfaces. This is actually the biggest reason why I create interfaces.
Defining behavior that may apply to many different classes that allows them to be used interchangeably, even when there isn't a relationship (other than the defined behavior) between the classes. For example, a Horse and a Bicycle class may both have a Ride method. You can define an interface IRideable that defines the Ride behavior and any class that uses this behavior can use either a Horse or Bicycle object without forcing an unnatural inheritance between them.
The argument against them is thus: If
a class is properly setup (with its
public and private members) then an
interface is just extra overhead
because those that use the class are
restricted to public members. If you
need to have an interface that is
implemented by more than 1 class then
just setup inheritance/polymorphism.
Consider the following code:
interface ICrushable
{
void Crush();
}
public class Vehicle
{
}
public class Animal
{
}
public class Car : Vehicle, ICrushable
{
public void Crush()
{
Console.WriteLine( "Crrrrrassssh" );
}
}
public class Gorilla : Animal, ICrushable
{
public void Crush()
{
Console.WriteLine( "Sqqqquuuuish" );
}
}
Does it make any sense at all to establish a class hierarchy that relates Animals to Vehicles even though both can be crushed by my giant crushing machine? No.
In addition to things explained in other answers, interfaces allow you simulate multiple inheritance in .NET which otherwise is not allowed.
Alas as someone said
Technology is dominated by two types of people: those who understand what they do not manage, and those who manage what they do not understand.
To enable unit testing of the class.
To track dependencies efficiently (if the interface isn't checked out and touched, only the semantics of the class can possibly have changed).
Because there is no runtime overhead.
To enable dependency injection.
...and perhaps because it's friggin' 2009, not the 70's, and modern language designers actually have a clue about what they are doing?
Not that interfaces should be thrown at every class interface: just those which are central to the system, and which are likely to experience significant change and/or extension.
Interfaces and abstract classes model different things. You derive from a class when you have an isA relationship so the base class models something concrete. You implement an interface when your class can perform a specific set of tasks.
Think of something that's Serializable, it doesn't really make sense (from a design/modelling point of view) to have a base class called Serializable as it doesn't make sense to say something isA Serializable. Having something implement a Serializable interface makes more sense as saying 'this is something the class can do, not what the class is'
Interfaces are not 'required for' at all, it's a design decision. I think you need to convince yourself, why, on a case-by-case basis, it is beneficial to use an interface, because there IS an overhead in adding an interface. On the other hand, to counter the argument against interfaces because you can 'simply' use inheritance: inheritance has its draw backs, one of them is that - at least in C# and Java - you can only use inheritance once(single inheritance); but the second - and maybe more important - is that, inheritance requires you to understand the workings of not only the parent class, but all of the ancestor classes, which makes extension harder but also more brittle, because a change in the parent class' implementation could easily break the subclasses. This is the crux of the "composition over inheritance" argument that the GOF book taught us.
You've been given a set of guidelines that your bosses have thought appropriate for your workplace and problem domain. So to be persuasive about changing those guidelines, it's not about proving that interfaces are a good thing in general, it's about proving that you need them in your workplace.
How do you prove that you need interfaces in the code you write in your workplace? By finding a place in your actual codebase (not in some code from somebody else's product, and certainly not in some toy example about Duck implementing the makeNoise method in IAnimal) where an interface-based solution is better than an inheritance-based solution. Show your bosses the problem you're facing, and ask whether it makes sense to modify the guidelines to accommodate situations like that. It's a teachable moment where everyone is looking at the same facts instead of hitting each other over the head with generalities and speculations.
The guideline seems to be driven by a concern about avoiding overengineering and premature generalisation. So if you make an argument along the lines of we should have an interface here just in case in future we have to..., it's well-intentioned, but for your bosses it sets off the same over-engineering alarm bells that motivated the guideline in the first place.
Wait until there's a good objective case for it, that goes both for the programming techniques you use in production code and for the things you start arguments with your managers about.
Test Driven Development
Unit Testing
Without interfaces producing decoupled code would be a pain. Best practice is to code against an interface rather than a concrete implementation. Interfaces seem rubbish at first but once you discover the benefits you'll always use them.
You can implement multiple interfaces. You cannot inherit from multiple classes.
..that's it. The points others are making about code decoupling and test-driven development don't get to the crux of the matter because you can do those things with abstract classes too.
Interfaces allow you to declare a concept that can be shared amongst many types (IEnumerable) while allowing each of those types to have its own inheritance hierarchy.
In this case, what we're saying is "this thing can be enumerated, but that is not its single defining characteristic".
Interfaces allow you to make the minimum amount of decisions necessary when defining the capabilities of the implementer. When you create a class instead of an interface, you have already declared that your concept is class-only and not usable for structs. You also make other decisions when declaring members in a class, such as visibility and virtuality.
For example, you can make an abstract class with all public abstract members, and that is pretty close to an interface, but you have declared that concept as overridable in all child classes, whereas you wouldn't have to have made that decision if you used an interface.
They also make unit testing easier, but I don't believe that is a strong argument, since you can build a system without unit tests (not recommended).
If your shop is performing automated testing, interfaces are a great boon to dependency injection and being able to test a unit of software in isolation.
The problem with the inheritance argument is that you'll either have a gigantic god class or a hierarchy so deep, it'll make your head spin. On top of that, you'll end up with methods on a class you don't need or don't make any sense.
I see a lot of "no multiple inheritance" and while that's true, it probably won't phase your team because you can have multiple levels of inheritance to get what they'd want.
An IDisposable implementation comes to mind. Your team would put a Dispose method on the Object class and let it propagate through the system whether or not it made sense for an object or not.
An interface declares a contract that any object implementing it will adhere to. This makes ensuring quality in code so much easier than trying to enforce written (not code) or verbal structure, the moment a class is decorated with the interface reference the requirements/contract is clear and the code won't compile till you've implemented that interface completely and type-safe.
There are many other great reasons for using Interfaces (listed here) but probably don't resonate with management quite as well as a good, old-fashioned 'quality' statement ;)
Well, my 1st reaction is that if you've to explain why you need interfaces, it's a uphill battle anyways :)
that being said, other than all the reasons mentioned above, interfaces are the only way for loosely coupled programming, n-tier architectures where you need to update/replace components on the fly etc. - in personal experience however that was too esoteric a concept for the head of architecture team with the result that we lived in dll hell - in the .net world no-less !
Please forgive me for the pseudo code in advance!
Read up on SOLID principles. There are a few reasons in the SOLID principles for using Interfaces. Interfaces allow you to decouple your dependancies on implementation. You can take this a step further by using a tool like StructureMap to really make the coupling melt away.
Where you might be used to
Widget widget1 = new Widget;
This specifically says that you want to create a new instance of Widget. However if you do this inside of a method of another object you are now saying that the other object is directly dependent on the use of Widget. So we could then say something like
public class AnotherObject
{
public void SomeMethod(Widget widget1)
{
//..do something with widget1
}
}
We are still tied to the use of Widget here. But at least this is more testable in that we can inject the implementation of Widget into SomeMethod. Now if we were to use an Interface instead we could further decouple things.
public class AnotherObject
{
public void SomeMethod(IWidget widget1)
{
//..do something with widget1
}
}
Notice that we are now not requiring a specific implementation of Widget but instead we are asking for anything that conforms to IWidget interface. This means that anything could be injected which means that in the day to day use of the code we could inject an actual implementation of Widget. But this also means that when we want to test this code we could inject a fake/mock/stub (depending on your understanding of these terms) and test our code.
But how can we take this further. With the use of StructureMap we can decouple this code even more. With the last code example our calling code my look something like this
public class AnotherObject
{
public void SomeMethod(IWidget widget1)
{
//..do something with widget1
}
}
public class CallingObject
{
public void AnotherMethod()
{
IWidget widget1 = new Widget();
new AnotherObject().SomeMethod(widget1);
}
}
As you can see in the above code we removed the dependency in the SomeMethod by passing in an object that conforms to IWidget. But in the CallingObject().AnotherMethod we still have the dependency. We can use StructureMap to remove this dependency too!
[PluginFamily("Default")]
public interface IAnotherObject
{
...
}
[PluginFamily("Default")]
public interface ICallingObject
{
...
}
[Pluggable("Default")]
public class AnotherObject : IAnotherObject
{
private IWidget _widget;
public AnotherObject(IWidget widget)
{
_widget = widget;
}
public void SomeMethod()
{
//..do something with _widget
}
}
[Pluggable("Default")]
public class CallingObject : ICallingObject
{
public void AnotherMethod()
{
ObjectFactory.GetInstance<IAnotherObject>().SomeMethod();
}
}
Notice that no where in the above code are we instantiating an actual implementation of AnotherObject. Because everything is wired for StructurMap we can allow StructureMap to pass in the appropriate implementations depending on when and where the code is ran. Now the code is truely flexible in that we can specify via configuration or programatically in a test which implementation we want to use. This configuration can be done on the fly or as part of a build process, etc. But it doesn't have to be hard wired anywhere.
Appologies as this doesn't answer your question regarding a case for Interfaces.
However I suggest getting the person in question to read..
Head First Design Patterns
-- Lee
I don't understand how its extra overhead.
Interfaces provide flexibility, manageable code, and reusability. Coding to an interface you don't need to worry about the concreted implementation code or logic of the certain class you are using. You just expect a result. Many class have different implementation for the same feature thing (StreamWriter,StringWriter,XmlWriter)..you do not need to worry about how they implement the writing, you just need to call it.
Related
I am preparing for an interview and decided to brush up my OOP concepts.
There are hundreds of articles available, but it seems each describes them differently.
Some says
Abstraction is "the process of identifying common patterns that have
systematic variations; an abstraction represents the common pattern
and provides a means for specifying which variation to use" (Richard
Gabriel).
and is achieved through abstract classes.
Some other says
Abstraction means to show only the necessary details to the client of
the object
and
Let’s say you have a method "CalculateSalary" in your Employee class,
which takes EmployeeId as parameter and returns the salary of the
employee for the current month as an integer value. Now if someone
wants to use that method. He does not need to care about how Employee
object calculates the salary? An only thing he needs to be concern is
name of the method, its input parameters and format of resulting
member,
I googled again and again and none of the results seem to give me a proper answer.
Now, where does encapsulation fit in all these?
I searched and found a stack overflow question. Even the answers to that questions were confusing
Here, it says
Encapsulation is a strategy used as part of abstraction. Encapsulation
refers to the state of objects - objects encapsulate their state and
hide it from the outside; outside users of the class interact with it
through its methods, but cannot access the classes state directly. So
the class abstracts away the implementation details related to its
state.
And here another reputed member says,
They are different concepts.
Abstraction is the process of refining away all the
unneeded/unimportant attributes of an object and keep only the
characteristics best suitable for your domain.
Now I m messed up with the whole concept. I know about abstract class, inheritance, access specifiers and all. I just want to know how should I answer when I am asked about abstraction and/or encapsulation in an interview.
Please don't mark it as a duplicate. I know there are several similar questions. But I want to avoid the confusion among the conflicting explanations. Can anyone suggest a credible link? A link to stackoverflow question is also welcome unless it creates confusion again. :)
EDIT: I need answers, a bit c# oriented
Encapsulation: hiding data using getters and setters etc.
Abstraction: hiding implementation using abstract classes and interfaces etc.
Abstraction means to show only the necessary details to the client of the object
Actually that is encapsulation. also see the first part of the wikipedia article in order to not be confused by encapsulation and data hiding. http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)
keep in mind that by simply hiding all you class members 1:1 behind properties is not encapsulation at all. encapsulation is all about protecting invariants and hiding of implementation details.
here a good article about that.
http://blog.ploeh.dk/2012/11/27/Encapsulationofproperties/
also take a look at the articles linked in that article.
classes, properties and access modifiers are tools to provide encapsulation in c#.
you do encapsulation in order to reduce complexity.
Abstraction is "the process of identifying common patterns that have systematic variations; an abstraction represents the common pattern and provides a means for specifying which variation to use" (Richard Gabriel).
Yes, that is a good definition for abstraction.
They are different concepts.
Abstraction is the process of refining away all the unneeded/unimportant attributes of an object and keep only the characteristics best suitable for your domain.
Yes, they are different concepts. keep in mind that abstraction is actually the opposite of making an object suitable for YOUR domain ONLY. it is in order to make the object suitable for the domain in general!
if you have a actual problem and provide a specific solution, you can use abstraction to formalize a more generic solution that can also solve more problems that have the same common pattern. that way you can increase the re-usability for your components or use components made by other programmers that are made for the same domain, or even for different domains.
good examples are classes provided by the .net framework, for example list or collection. these are very abstract classes that you can use almost everywhere and in a lot of domains. Imagine if .net only implemented a EmployeeList class and a CompanyList that could only hold a list of employees and companies with specific properties. such classes would be useless in a lot of cases. and what a pain would it be if you had to re-implement the whole functionality for a CarList for example. So the "List" is ABSTRACTED away from Employee, Company and Car. The List by itself is an abstract concept that can be implemented by its own class.
Interfaces, abstract classes or inheritance and polymorphism are tools to provide abstraction in c#.
you do abstraction in order to provide reusability.
Image source
Abstraction: is shown in the top left and the top right images of the cat. The surgeon and the old lady designed (or visualized) the animal differently. In the same way, you would put different features in the Cat class, depending upon the need of the application. Every cat has a liver, bladder, heart, and lung, but if you need your cat to 'purr' only, you will abstract your application's cat to the design on top-left rather than the top-right.
Encapsulation: is demonstrated by the cat standing on the table. That's what everyone outside the cat should see the cat as. They need not worry whether the actual implementation of the cat is the top-left one or the top-right one, or even a combination of both.
Another detailed answer here.
I will try to demonstrate Encapsulation and Abstraction in a simple way.. Lets see..
The wrapping up of data and functions into a single unit (called
class) is known as encapsulation. Encapsulation containing and hiding
information about an object, such as internal data structures and
code.
Encapsulation is -
Hiding Complexity,
Binding Data and Function together,
Making Complicated Method's Private,
Making Instance Variable's Private,
Hiding Unnecessary Data and Functions from End User.
Encapsulation implements Abstraction.
And Abstraction is -
Showing Whats Necessary,
Data needs to abstract from End User,
Lets see an example-
The below Image shows a GUI of "Customer Details to be ADD-ed into a Database".
By looking at the Image we can say that we need a Customer Class.
Step - 1: What does my Customer Class needs?
i.e.
2 variables to store Customer Code and Customer Name.
1 Function to Add the Customer Code and Customer Name into Database.
namespace CustomerContent
{
public class Customer
{
public string CustomerCode = "";
public string CustomerName = "";
public void ADD()
{
//my DB code will go here
}
Now only ADD method wont work here alone.
Step -2: How will the validation work, ADD Function act?
We will need Database Connection code and Validation Code (Extra Methods).
public bool Validate()
{
//Granular Customer Code and Name
return true;
}
public bool CreateDBObject()
{
//DB Connection Code
return true;
}
class Program
{
static void main(String[] args)
{
CustomerComponent.Customer obj = new CustomerComponent.Customer;
obj.CustomerCode = "s001";
obj.CustomerName = "Mac";
obj.Validate();
obj.CreateDBObject();
obj.ADD();
}
}
Now there is no need of showing the Extra Methods(Validate(); CreateDBObject() [Complicated and Extra method] ) to the End User.End user only needs to see and know about Customer Code, Customer Name and ADD button which will ADD the record.. End User doesn't care about HOW it will ADD the Data to Database?.
Step -3: Private the extra and complicated methods which doesn't involves End User's Interaction.
So making those Complicated and Extra method as Private instead Public(i.e Hiding those methods) and deleting the obj.Validate(); obj.CreateDBObject(); from main in class Program we achieve Encapsulation.
In other words Simplifying Interface to End User is Encapsulation.
So now the complete code looks like as below -
namespace CustomerContent
{
public class Customer
{
public string CustomerCode = "";
public string CustomerName = "";
public void ADD()
{
//my DB code will go here
}
private bool Validate()
{
//Granular Customer Code and Name
return true;
}
private bool CreateDBObject()
{
//DB Connection Code
return true;
}
class Program
{
static void main(String[] args)
{
CustomerComponent.Customer obj = new CustomerComponent.Customer;
obj.CustomerCode = "s001";
obj.CustomerName = "Mac";
obj.ADD();
}
}
Summary :
Step -1: What does my Customer Class needs? is Abstraction.
Step -3: Step -3: Private the extra and complicated methods which doesn't involves End User's Interaction is Encapsulation.
P.S. - The code above is hard and fast.
UPDATE:
There is an video on this link to explain the sample:
What is the difference between Abstraction and Encapsulation
Below is a semester long course distilled in a few paragraphs.
Object-Oriented Analysis and Design (OOAD) is actually based on not just two but four principles. They are:
Abstraction: means that you only incorporate those features of an entity which are required in your application. So, if every bank account has an opening date but your application doesn't need to know an account's opening date, then you simply don't add the OpeningDate field in your Object-Oriented Design (of the BankAccount class). †Abstraction in OOAD has nothing to do with abstract classes in OOP.
Per the principle of Abstraction, your entities are an abstraction of what they are in the real world. This way, you design an abstraction of Bank Account down to only that level of detail that is needed by your application.
Inheritance: is more of a coding-trick than an actual principle. It saves you from re-writing those functionalities that you have written somewhere else. However, the thinking is that there must be a relation between the new code you are writing and the old code you are wanting to re-use. Otherwise, nobody prevents you from writing an Animal class which is inheriting from BankAccount, even if it is totally non-sensical.
Just like you may inherit your parents' wealth, you may inherit fields and methods from your parent class. So, taking everything that parent class has and then adding something more if need be, is inheritance. Don't go looking for inheritance in your Object Oriented Design. Inheritance will naturally present itself.
Polymorphism: is a consequence of inheritance. Inheriting a method from the parent is useful, but being able to modify a method if the situation demands, is polymorphism. You may implement a method in the subclass with exactly the same signature as in parent class so that when called, the method from child class is executed. This is the principle of Polymorphism.
Encapsulation: implies bundling the related functionality together and giving access to only the needful. Encapsulation is the basis of meaningful class designing in Object Oriented Design, by:
putting related data and methods together; and,
exposing only the pieces of data and methods relevant for functioning with external entities.
Another simplified answer is here.
† People who argue that "Abstraction of OOAD results in the abstract keyword of OOP"... Well that is incorrect.
Example: When you design a University in an application using object oriented principles, you only design an "abstraction" of the university. Even though there is usually one cash dispensing ATM in almost every university, you may not incorporate that fact if it's not needed for your application. And now though you have designed only an abstraction of the university, you are not required to put abstract in your class declaration. Your abstract design of university will be a normal class in your application.
I think they are slightly different concepts, but often they are applied together. Encapsulation is a technique for hiding implementation details from the caller, whereas abstraction is more a design philosophy involving creating objects that are analogous to familiar objects/processes, to aid understanding. Encapsulation is just one of many techniques that can be used to create an abstraction.
For example, take "windows". They are not really windows in the traditional sense, they are just graphical squares on the screen. But it's useful to think of them as windows. That's an abstraction.
If the "windows API" hides the details of how the text or graphics is physically rendered within the boundaries of a window, that's encapsulation.
my 2c
the purpose of encapsulation is to hide implementation details from the user of your class e.g. if you internally keep a std::list of items in your class and then decide that a std::vector would be more effective you can change this without the user caring. That said, the way you interact with the either stl container is thanks to abstraction, both the list and the vector can for instance be traversed in the same way using similar methods (iterators).
One example has always been brought up to me in the context of abstraction; the automatic vs. manual transmission on cars. The manual transmission hides some of the workings of changing gears, but you still have to clutch and shift as a driver. Automatic transmission encapsulates all the details of changing gears, i.e. hides it from you, and it is therefore a higher abstraction of the process of changing gears.
Encapsulation: Hiding implementation details (NOTE: data AND/OR methods) such that only what is sensibly readable/writable/usable by externals is accessible to them, everything else is "untouchable" directly.
Abstraction: This sometimes refers specifically to a type that cannot be instantiated and which provides a template for other types that can be, usually via subclassing. More generally "abstraction" refers to making/having something that is less detailed, less specific, less granular.
There is some similarity, overlap between the concepts but the best way to remember it is like this: Encapsulation is more about hiding the details, whereas abstraction is more about generalizing the details.
Abstraction and Encapsulation are confusing terms and dependent on each other.
Let's take it by an example:
public class Person
{
private int Id { get; set; }
private string Name { get; set; }
private string CustomName()
{
return "Name:- " + Name + " and Id is:- " + Id;
}
}
When you created Person class, you did encapsulation by writing properties and functions together(Id, Name, CustomName). You perform abstraction when you expose this class to client as
Person p = new Person();
p.CustomName();
Your client doesn't know anything about Id and Name in this function.
Now if, your client wants to know the last name as well without disturbing the function call. You do encapsulation by adding one more property into Person class like this.
public class Person
{
private int Id { get; set; }
private string Name { get; set; }
private string LastName {get; set;}
public string CustomName()
{
return "Name:- " + Name + " and Id is:- " + Id + "last name:- " + LastName;
}
}
Look, even after addding an extra property in class, your client doesn't know what you did to your code. This is where you did abstraction.
As I knowit, encapsulation is hiding data of classes in themselves, and only making it accessible via setters / getters, if they must be accessed from the outer world.
Abstraction is the class design for itself.
Means, how You create Your class tree, which methods are general ones, which are inherited, which can be overridden,which attributes are only on private level, or on protected, how Do You build up Your class inheritance tree, Do You use final classes, abtract classes, interface-implementation.
Abstraction is more placed the oo-design phase, while encapsulation also enrolls into developmnent-phase.
I think of it this way, encapsulation is hiding the way something gets done. This can be one or many actions.
Abstraction is related to "why" I am encapsulating it the first place.
I am basically telling the client "You don't need to know much about how I process the payment and calculate shipping, etc. I just want you to tell me you want to 'Checkout' and I will take care of the details for you."
This way I have encapsulated the details by generalizing (abstracting) into the Checkout request.
I really think that abstracting and encapsulation go together.
Abstraction
In Java, abstraction means hiding the information to the real world. It establishes the contract between the party to tell about “what should we do to make use of the service”.
Example, In API development, only abstracted information of the service has been revealed to the world rather the actual implementation. Interface in java can help achieve this concept very well.
Interface provides contract between the parties, example, producer and consumer. Producer produces the goods without letting know the consumer how the product is being made. But, through interface, Producer let all consumer know what product can buy. With the help of abstraction, producer can markets the product to their consumers.
Encapsulation:
Encapsulation is one level down of abstraction. Same product company try shielding information from each other production group. Example, if a company produce wine and chocolate, encapsulation helps shielding information how each product Is being made from each other.
If I have individual package one for wine and another one for
chocolate, and if all the classes are declared in the package as
default access modifier, we are giving package level encapsulation
for all classes.
Within a package, if we declare each class filed (member field) as
private and having a public method to access those fields, this way
giving class level encapsulation to those fields
Let's go back 6 million years,
Humans are not fully evolved. To begin with, evolution created a hole next to each body part to inject nutrients, which you can decide on yourself.
However, as humans get older, the nutrient requirements for each body part change Humans don't know which body parts need how much of which nutrient.
Evolution realised that exposing the hole next to each body part was a mistake, so it corrected it by encapsulating the entire body in skin and exposing only one opening, later it was called as "mouth."
Also, it abstracted the whole implementation of nutrient allocation through digestive system. All you have to do is keep eating through your mouth. The digestive system will take care of the body's nutrient composition changes to meet your needs.
In the software world, requirements will keep changing.
Encapsulating the internal data and exposing only the required functions will help with better maintenance. As a result, you have greater control over what occurs within your class/module/framework.
Abstraction makes it easier for the client to consume a class/module/framework. So clients don't have to do(know) 100 different steps to get the desired output. Exposed function/class will do all the work. In our example, you don't have to worry about which nutrients are required for which body part. Just eat it.
I have a class A that depends on 10 other classes. According to Dependency Injection pattern, i should pass all dependencies of A by its constructor.
So lets assume this constructor (of course this is not a working or real code, since I am not allowed to post the real code here)
public ClassA(ClassB b, ClassC c, ClassD d, ClassE e, ClassF f, ClassG g, ClassH h, ClassI i) {
this.b = b;
this.c = c;
this.d = d;
this.e = e;
this.f = f;
this.g = g;
this.h = h;
this.i = i;
}
I have read on Martin Fowler's book about refactoring that having a method with a lot of parameters is a code smell and should not happen.
My question is: is this OK when we are talking about DI? Is there a better way of inject dependencies without breaking Martin Fowler's rules?
I know I could pass the dependencies through properties, but that may cause errors since no one is really sure what should be pass in order that the class works.
EDIT
Thanks for all your answers. I will try now to demonstrate some of class A dependencies:
1 - A class to access a DB
2 - Another class to access another DB (yes, i need to perform operations on two databases)
3 - A class to send error notifications by email
4 - A class to load configurations
5 - A class that will act as timer for some operations (maybe this one can be avoided)
6 - A class with business logic
There any many others that i am trying to get rid of, but those are really necessary and I dont see any ways of avoiding them.
EDIT
After some refactoring now i have 7 dependencies (down from 10). But I have 4 DAO objects:
CustomerDAO
ProcessDAO
ProductsDAO
CatalogDAO
Is it correct do create another class called MyProjectDAO and inject those DAOS onto it? This way I will have only one DAO class that aggregates all DAO objects of my project. I dont think this is a good idea because it violates the Single Responsibility Principle. Am I right?
In my experience:
Try to design your class so it needs fewer dependencies. If it needs that many, it may have too many responsibilities.
If you're really convinced that your class design is appropriate, consider whether it may make sense for some of those dependencies to be joined together (e.g. via an adapter which takes responsibility for one "big" operation your class needs by delegating to a few of the dependencies). You can then depend on the adapter instead of the "smaller" dependencies.
If every other bit really makes sense, just swallow the smell of having a lot of parameters. It happens sometimes.
Can you justify (to yourself) why the class depends on 10 other classes? Are there member variables you use to tie together a subset of those classes? If so, that indicates that this class should be broken up so that the extracted class would depend on the subset and the variables that tie such state together goes in the extracted class. With 10 dependencies, it's possible that this class has simply grown too large and needs to have its internals broken up anyway.
A note regarding your final sentence: such order dependency can also be a code smell, so it's probably good not to expose it in your interface. In fact, consider whether or not the order requirements are because operations need to be carried out in a specific order (it is the complexity of the algorithm or protocol), or because you've designed your classes to be inter-dependent. If the complexity is due to your design, refactor to eliminate the ordered dependency where possible.
If you cannot refactor (the complexities are all essential and you just have a terrible coordination problem on your hands), then you can abstract the ugliness and keep users of this class shielded (builder, factory, injector, etc).
Edit: Now that I have thought about it, I am not convinced that essential complexities of your algorithm or protocol cannot be abstracted a bit (though that might be the case). Depending on your specific problem, similarities in the manipulations of those dependent classes might either be better solved with the Strategy pattern or the Observer pattern (event listeners). You might have to wrap these classes in classes that adapt them to slightly different interfaces than what they currently expose. You'd have to evaluate the tradeoff of having the code in this monster class become more readable (yay) at the expense of up to 10 more classes in your project (boo).
I'd also like to make an addendum to abstracting the construction of this class. It seems important that any class that depends on this class also use the Dependency Injection pattern. That way, if you do use a builder, factory, injector, etc. you don't accidentally rob yourself of some of the benefits of using the DI pattern (the most important in my mind is the ability to substitute mock objects for testing).
Edit 2 (based on your edit):
My first thought is "what, no logging dependency?" :)
Even knowing what the dependencies are, it's difficult to offer useful advice.
First: what are the responsibilities of everyone? Why does this class depend on controller code (the business logic) and on Model code (two different database access classes, with DAO classes)?
Depending both on DAOs and DB access classes is a code smell. What is the purpose of a DAO? What is the purpose of the DB classes? Are you trying to operate at multiple levels of abstraction?
One of the principles of OO is that data and behavior get bundled into little things called classes. Have you violated this when you created this business logic class distinct from the objects it manipulates distinct from the DAO distinct from this class? Related: Take a brief diversion into SOLID.
Second: A class to load configurations. Smells bad. Dependency Injection helps you identify dependencies and swap them out. Your monster class that depends on certain parameters. These parameters are grouped into this configuration class because...? What is the name of this configuration class? Is it DBparameters? if so, it belongs to the DB object(s), not to this class. Is it generic like Configurations? If so, you've got a mini dependency injector right there (granted, it is probably only injecting string or int values instead of composite data like classes, but why?). Awkward.
Third: The most important lesson I learned from Refactoring was that my code sucked. Not only did my code suck, but there was no single transformation to make it stop sucking. The best I could hope for was to make it suck less. Once I did that, I could make it suck less again. And again. Some design patterns are bad, but they exist to allow your sucky code to transition to less sucky code. So you take your globals and make them singletons. Then you eliminate your singletons. Don't get discouraged because you've just refactored to find that your code still sucks. It sucks less. So, your Configuration loading object may smell, but you might decide that it isn't the smelliest part of your code. In fact, you may find that the effort to "fix" it isn't worth it.
Yes - a method taking this many parameters should be considered a code smell. Is this method truly only doing one thing and one thing only?
If this is still true you can still lower the number of dependencies by looking at the relationships between the dependencies - are any of them closely related, could they be coupled into aggregate dependencies? E.g. you could refactor by creating a new class K that uses A, B and C internally (injected into class K by constructor, then using composition) - so the number of parameters to the method would be reduced by two.
Rinse and repeat until aggregating doesn't make sense anymore and/or you have a reasonable number of parameters.
Also see a related blog post: "Refactoring to Aggregate Services"
I'd also advise to redesign your application. In case it is not possible you can pass your IoC container as a constructor parameter. If you do not want to couple your code with a concrete implementation you can always abstract it. The code will look something like this.
public interface IAbstractContainer
{
T Resolve<T>();
}
public class ConcreteContainer: IAbstractContainer
{
private IContainer _container; // E.g. Autofac container
public ConcreteContainer(IContainer container)
{
_container = container;
{
public T Resolve<T>()
{
return _container.Resolve<T>();
}
}
public classA(IAbstractContainer container)
{
this.B = container.Resolve<ClassB>();
this.C = container.Resolve<ClassC>();
...
}
}
A ConcreteContainer instance is injected the usual way.
I have looked on line for information that would help me solve a design issue that is confusing me. I am new to complicated inheritance situations so my solution could actually just be rooted in a better design. But in trying to figure out what my design should be, I keep ending up thinking I really just need to inherit more than 1 base class.
My specific case involves Assets and different types of Assets.
Starting with the Asset...
Every PhysicalDevice is an Asset
Every VirtualDevice is an Asset
Every Server is an Asset
Every PhysicalServer would need to be both a PhysicalDevice and a Server
Every VirtualServer would need to be both a VirtualDevice and a Server
Every NetDevice is a PhysicalDevice
Every StorageArray is a PhysicalDevice
One solution I guess is to duplicate the Server code for both PhysicalServers, and VirtualServers however, I feel like this goes against what im trying to do, which is inherit.
They need to be separate classes because each of the types will have properties and methods. For instance, Server will have OSCaption, Memory, Procs, etc. PhysicalDevice will have things like Location, Serial, Vendor etc. And VirtualDevice will have a ParentDevice, State, VHDLocation etc.
If the inheritance is liner then i run into the problem of not being able to describe these types accurately.
Something that seems intriguing is Interfaces. It seems that i can define all base classes as interfaces and implement them in my main classes as needed. but, I am simply unsure of what the implications are if I were to do that.
for instance, something like... PhysicalServer : IAsset : IServer : IPhysical
I am in deep water so I’m really just looking for suggestions or guidance.
Interfaces are an appropriate way of ensuring contract integrity across types, but you may end up with duplicate code for each implementation.
Your scenario may lend itself better to composition than inheritance (or a combination thereof).
Example - Inheritance + Composition
public class PhysicalServer : Asset
{
public PhysicalInfo PhysicalProperties
{
get;
set;
}
}
public class VirtualServer : Asset
{
public VirtualInfo VirtualProperties
{
get;
set;
}
}
Example - Composition Only
public class VirtualServer
{
public VirtualInfo VirtualProperties
{
get;
set;
}
public AssetInfo AssetProperties
{
get;
set;
}
}
You could then add polymorphism/generics into the mix and create derivatives of types to represent more specific needs.
Example - Inheritance + Composition + Genericized Member that inherits from a common type
public class VirtualServer<TVirtualInfo> : Asset
where TVirtualInfo : VirtualDeviceInfo
{
public TVirtualInfo VirtualProperties
{
get;
set;
}
}
public class VirtualServerInfo : VirtualDeviceInfo
{
// properties which are specific to virtual servers, not just devices
}
There are countless ways that you could model this out, but armed with interfaces, composition, inheritance, and generics you can come up with an effective data model.
Use mixins.
You first decide which is the primary thing you want your object to be. In your case I think it should be server.
public class PhysicalServer : Server
Then you add interfaces for the other functionalities.
public class PhysicalServer : Server,IAsset,IVirtualDevice
And you add extension methods to the interfaces.
public static int WordCount(this IAsset asset)
{
//do something on the asset
}
Here's an article on mixins in case my answer is too simple: http://www.zorched.net/2008/01/03/implementing-mixins-with-c-extension-methods/
C# doesn't support multiple inheritance from classes (but does support multiple implementations of interfaces).
What you're asking for is not multiple inheritance. Multiple inheritance is where a single class has more than one base class. In your example each class inherits from one/zero other classes. Asset and Server being the ultimate base classes. So you have no problem doing that in c#, you can just define the functionality common in eg server and then do different things in VirtualDevice and PhysicalDevice.
However you will end up with a possibly complex class hierarchy and many people would advocate composition over inheritance. This is where you'd have interfaces defining behaviour and classes implement the interface to say that they do something but each class can implement the interface methods differently. So your example for the PhysicalServer interfaces may be encouraged.
To start with remember that inheritance is the obvious result of the kind of problem that you have mentioned. Every class does have more than one behavior and everyone falls into this trap. So chill. You are not the first nor the last.
You need to modify your thinking a bit to break away from the norm.
You need to look at it from the angle of what "changes" in future rather than look at a hierarchical kind of class diagram. A class diagram may not be hierarchical instead it needs to represent "what changes" and what "remains constant". From what I see, in future you may define a MobileDevice, VirtualMobileDevice.
In your current classes you seem to have properties like Vendor, Serial. These may be needed in MobileDevice too right ? So you need to modify your thinking to actually think of behaviors instead of classes that make hierarchical sense.
Rethink, you are going down the track of multiple inheritance, very dangerous and complex design. Its not the correctness of your thought process that is in question here. Its the question of you coding something and someone up ahead in the near future complicating it beyond repair.
No multiple inheritance in java is there for this one reason, to ensure that you dont think the hierarchical way.
Think "factories" (for creation), strategy (for common functionality/processing).
Edited :
Infact you should also consider creating layers in the form of library, so that there is complete abstraction and control on the main parts of your processing. What ever you intend to do with the Asset/Device class should be abstracted into a library, which can be protected by change.
So I have an order manager class that looks like:
public class OrderManager
{
private IDBFactory _dbFactory;
private Order _order;
public OrderManager(IDBFactory dbFactory)
{
_dbFactory = dbFactory;
}
public void Calculate()
{
_order.SubTotal
_order.ShippingTotal
_order.TaxTotal
_order.GrandTotal
}
}
Now, the point here is to have a flexible/testible design.
I am very concerned about being able to write solid unit tests around this Calculate method.
Considerations:
1. Shipping has to be abstracted out, be loose coupled since the implementation of shipping could vary depending on USPS, UPS, fedex etc. (they have their own API's).
2. same goes with calculating tax
Should I just create a Tax and Shipping Manager class, and have a tax/shipping factory in the constructor? (exactly how I have designed my OrderManager) class?
(the only thing that I can think of, in terms of what I am "missing", is IoC, but I don't mind that and don't need that extra level of abstraction in my view).
Well, you are already moving towards dependency injection in your approach, so why not go the whole hog and use some sort of IoC container to handle this for you?
Yes, if you want it abstrated out, then create a separate class for it. If you want to truly unit test what is left, abstract out an interface and use mock testing. The problem is, the more you abstract out like this, the more plumbing together there is to do and the more you will find yourself wishing you were using an IoC framework of some kind.
You are suggesting constructor injection, which is a common approach. You also come across property injection (parameterless constructor, set properties instead). And there are also frameworks that ask you to implement an initialization interface of some kind that allows the IoC framework to do the initialization for you in a method call. Use whatever you feel most comfortable with.
I do think an IOC would help with the plumbing of instantiating the correct concrete classes but you still need to get your design the way you want it. I do think you need to abstract away the shipping with an interface that you can implement with a class for each of your shippers (USPS, UPS, FEDEx, etc) and could use a Factory class (ShippingManager) to pass the correct one out or depend on the IOC to do that for you.
public interface IShipper
{
//whatever goes into calculating shipping.....
decimal CalculateShippingCost(GeoData geo, decimal packageWeight);
}
You could also just inject an IShipper and ITaxer concrete classes into your OrderManager and you calculate method just calls into those classes....and can use an IOC nicely to handle that.
Just a thought:
Your Calculate() method taking no parameters, returning nothing and acting on private fields is not how I would do it. I would write it as a static method that takes in some numbers, an IShippingProvider and an ITaxJurisdiction and returns a dollar total. That way you have an opportunity to cache the expensive calls to UPS and your tax tables using memoization.
Could be that I'm prejudiced against public methods that work like that. They have burned me in the past trying to bind to controls, use code generators, etc.
EDIT: as for dependency injection/IOC, I don't see the need. This is what interfaces were made for. You're not going to be loading up a whole array of wacky classes, just some implementations of the same weight/zipcode combo.
That's what I would say if I were your boss.
I would take the Calculate method out into a class. Depending on your circumstances OrderCalculator might need to be aware of VAT, Currency, Discounts, ...
Just a thought.
Every so often, I run into a case where I want a collection of classes all to possess similar logic. For example, maybe I want both a Bird and an Airplane to be able to Fly(). If you're thinking "strategy pattern", I would agree, but even with strategy, it's sometimes impossible to avoid duplicating code.
For example, let's say the following apply (and this is very similar to a real situation I recently encountered):
Both Bird and Airplane need to hold an instance of an object that implements IFlyBehavior.
Both Bird and Airplane need to ask the IFlyBehavior instance to Fly() when OnReadyToFly() is called.
Both Bird and Airplane need to ask the IFlyBehavior instance to Land() when OnReadyToLand() is called.
OnReadyToFly() and OnReadyToLand() are private.
Bird inherits Animal and Airplane inherits PeopleMover.
Now, let's say we later add Moth, HotAirBalloon, and 16 other objects, and let's say they all follow the same pattern.
We're now going to need 20 copies of the following code:
private IFlyBehavior _flyBehavior;
private void OnReadyToFly()
{
_flyBehavior.Fly();
}
private void OnReadyToLand()
{
_flyBehavior.Land();
}
Two things I don't like about this:
It's not very DRY (the same nine lines of code are repeated over and over again). If we discovered a bug or added a BankRight() to IFlyBehavior, we would need to propogate the changes to all 20 classes.
There's not any way to enforce that all 20 classes implement this repetitive internal logic consistently. We can't use an interface because interfaces only permit public members. We can't use an abstract base class because the objects already inherit base classes, and C# doesn't allow multiple inheritance (and even if the classes didn't already inherit classes, we might later wish to add a new behavior that implements, say, ICrashable, so an abstract base class is not always going to be a viable solution).
What if...?
What if C# had a new construct, say pattern or template or [fill in your idea here], that worked like an interface, but allowed you to put private or protected access modifiers on the members? You would still need to provide an implementation for each class, but if your class implemented the PFlyable pattern, you would at least have a way to enforce that every class had the necessary boilerplate code to call Fly() and Land(). And, with a modern IDE like Visual Studio, you'd be able to automatically generate the code using the "Implement Pattern" command.
Personally, I think it would make more sense to just expand the meaning of interface to cover any contract, whether internal (private/protected) or external (public), but I suggested adding a whole new construct first because people seem to be very adamant about the meaning of the word "interface", and I didn't want semantics to become the focus of people's answers.
Questions:
Regardless of what you call it, I'd like to know whether the feature I'm suggesting here makes sense. Do we need some way to handle cases where we can't abstract away as much code as we'd like, due to the need for restrictive access modifiers or for reasons outside of the programmer's control?
Update
From AakashM's comment, I believe there is already a name for the feature I'm requesting: a Mixin. So, I guess my question can be shortened to: "Should C# allow Mixins?"
The problem you describe could be solved using the Visitor pattern (everything can be solved using the Visitor pattern, so beware! )
The visitor pattern lets you move the implementation logic towards a new class. That way you do not need a base class, and a visitor works extremely well over different inheritance trees.
To sum up:
New functionality does not need to be added to all different types
The call to the visitor can be pulled up to the root of each class hierarchy
For a reference, see the Visitor pattern
Cant we use extension methods for this
public static void OnReadyToFly(this IFlyBehavior flyBehavior)
{
_flyBehavior.Fly()
}
This mimics the functionality you wanted (or Mixins)
Visual Studio already offers this in 'poor mans form' with code snippets. Also, with the refactoring tools a la ReSharper (and maybe even the native refactoring support in Visual Studio), you get a long way in ensuring consistency.
[EDIT: I didn't think of Extension methods, this approach brings you even further (you only need to keep the _flyBehaviour as a private variable). This makes the rest of my answer probably obsolete...]
However; just for the sake of the discussion: how could this be improved? Here's my suggestion.
One could imagine something like the following to be supported by a future version of the C# compiler:
// keyword 'pattern' marks the code as eligible for inclusion in other classes
pattern WithFlyBehaviour
{
private IFlyBehavior_flyBehavior;
private void OnReadyToFly()
{
_flyBehavior.Fly();
}
[patternmethod]
private void OnReadyToLand()
{
_flyBehavior.Land();
}
}
Which you could use then something like:
// probably the attribute syntax can not be reused here, but you get the point
[UsePattern(FlyBehaviour)]
class FlyingAnimal
{
public void SetReadyToFly(bool ready)
{
_readyToFly = ready;
if (ready) OnReadyToFly(); // OnReadyToFly() callable, although not explicitly present in FlyingAnimal
}
}
Would this be an improvement? Probably. Is it really worth it? Maybe...
You just described aspect oriented programming.
One popular AOP implementation for C# seems to be PostSharp (Main site seems to be down/not working for me though, this is the direct "About" page).
To follow up on the comment: I'm not sure if PostSharp supports it, but I think you are talking about this part of AOP:
Inter-type declarations provide a way
to express crosscutting concerns
affecting the structure of modules.
Also known as open classes, this
enables programmers to declare in one
place members or parents of another
class, typically in order to combine
all the code related to a concern in
one aspect.
Could you get this sort of behavior by using the new ExpandoObject in .NET 4.0?
Scala traits were developed to address this kind of scenario. There's also some research to include traits in C#.
UPDATE: I created my own experiment to have roles in C#. Take a look.
I will use extension methods to implement the behaviour as the code shows.
Let Bird and Plane objects implement a property for IFlyBehavior object for an interface IFlyer
public interface IFlyer
{
public IFlyBehavior FlyBehavior
}
public Bird : IFlyer
{
public IFlyBehaviour FlyBehavior {get;set;}
}
public Airplane : IFlyer
{
public IFlyBehaviour FlyBehavior {get;set;}
}
Create an extension class for IFlyer
public IFlyerExtensions
{
public void OnReadyToFly(this IFlyer flyer)
{
flyer.FlyBehavior.Fly();
}
public void OnReadyToLand(this IFlyer flyer)
{
flyer.FlyBehavior.Land();
}
}