I am implementing IServiceLocator(CommonServiceLocator package) into my custom ServiceLocator class.
The interface has the following methods to implement:
public class CustomServiceLocator : IServiceLocator
{
private IServiceProvider _provider;
public RatioDissectionServiceLocator(IServiceProvider provider)
{
_provider = provider;
}
public IEnumerable<object> GetAllInstances(Type serviceType)
{
throw new NotImplementedException();
}
public IEnumerable<TService> GetAllInstances<TService>()
{
throw new NotImplementedException();
}
public object GetInstance(Type serviceType)
{
throw new NotImplementedException();
}
public object GetInstance(Type serviceType, string key)
{
throw new NotImplementedException();
}
public TService GetInstance<TService>()
{
return _provider.GetService<TService>();
}
}
I don't want to implement all the methods in my class. How can we achieve ISP for inbuilt C# interfaces?
Any help?
The Interface Segregation Principle states:
No client should be forced to depend on methods it does not use.
What this means is that despite many unclear and misleading explanations of the principle, a big interface by itself doesn't violate the principle. Perhaps another class actually does depend on all the members of the interface. So we wouldn't look at an interface like IServiceLocator and try to "fix" it somehow.
The ISP is from the point of view of classes that depend on interfaces. If an interface has 20 members and my class depends on all of them, it's not an ISP violation. (It's likely all sorts of other bad things that have nothing to do with the ISP.) If another class depends on the exact same interface and uses only a few members, that's an ISP violation.
In both examples it's the same interface. The principle isn't about the interface. It's about whether or not a class that depends on the interface uses all of its members.
(Another weird example I see a lot is a big interface and a class that implements the interface but throws NotImplementedException for some members. That's also bad, and it's a Liskov Substitution violation, but it has nothing at all to do with ISP. Implementing an interface is not depending on it.)
One way to avoid ISP violations is to write interfaces from the perspective of classes that depend on them. Whatever your class needs from its dependency, write your interface to describe exactly that. If the concrete inner implementation is a framework class with 100 members, wrap it in your own class:
public interface ISmallSegregatedInterface
{
void DoJustWhatMyClassNeeds();
}
public class TheImplementation : ISmallSegregatedInterface
{
private readonly FrameworkClassWithLotsOfMembers _inner;
public TheImplementation(FrameworkClassWithLotsOfMembers inner)
{
_inner = inner;
}
public void DoJustWhatMyClassNeeds()
{
_inner.CallSomeMethod();
}
}
Now the class that needs to depend on one method can depend on an interface with just that one method. (Over time I've found that this leads to lots of single-method interfaces. I think that logically leads to depending on functions and delegates but a single-method interface is okay.
That is interface segregation. Your classes don't depend on a big interface they don't need. They depend on one ore more interfaces that describe exactly what they need. This is often accomplished by creating the interface from the perspective of the class that needs to depend on it.
What you might find is that no class needs to depend on all of the methods of IServiceLocator.
Maybe all you need is this:
TService GetInstance<TService>();
But does a class really need to depend on a method that can return anything? In other words, you're probably only going to request one or two dependencies. So maybe what you really need is this:
public interface ISomethingSpecificFactory
{
ISomethingSpecific CreateInstance();
}
Or you might find that you don't need the factory at all - perhaps you can just inject ISomethingSpecific instead of a factory that creates an instance of ISomethingSpecific.
Another way of looking at it: If you don't need to implement all of the methods of IServiceLocator then you don't need to create a class that implements IServiceLocator.
IServiceLocator is a framework interface. Unlike most software we create, it doesn't exist to meet a narrow, specific need. It meets a broader variety of needs that are determined as we write our software. That's why it makes more sense that it has all sorts of varied methods we might not need.
One reason for the ISP is that if lots of classes depend on different members of an interface, we might be pressured to change the interface because of the needs of one client, and those changes affect other clients that depend on other methods, in effect coupling them all together.
We can't change IServiceLocator so that pressure doesn't exist. So technically, even if we did violate the ISP by depending on that interface, it wouldn't have the harmful effect that the ISP protects us from.
Related
I'm fairly new to programming and i'm having trouble to understand how to apply effectively the principle showed in the following link (the ATM one):
http://www.objectmentor.com/resources/articles/isp.pdf
Basically it starts with a design that does not complain the ISP (Interface Segregation Principle), and moves forward to refactor the behavior into different interfaces.
My question is: Don't we use interfaces to express common behaviour among not so (or not) related abstractions?
What's the point of encapsulating methods in an interface, if not even one is going to be shared with the classes that are going to implement them? In which scenario this could be consider useful?
If we continue the line of the example, the following code is given:
public interface ITransaction
{
void Execute();
}
public interface IDepositUi
{
void RequestDepositAmount();
}
public class DepositTransaction : ITransaction
{
private IDepositUi depositUI;
public DepositTransaction(IDepositUi ui)
{
depositUI = ui;
}
public virtual void Execute()
{
/*code*/
depositUI.RequestDepositAmount();
/*code*/
}
}
public interface WithdrawalUI
{
void RequestWithdrawalAmount();
}
public class WithdrawalTransaction : ITransaction
{
private WithdrawalUI withdrawalUI;
public WithdrawalTransaction(WithdrawalUI ui)
{
withdrawalUI = ui;
}
public virtual void Execute()
{
/*code*/
withdrawalUI.RequestWithdrawalAmount(); /*code*/
}
}
public interface TransferUI
{
void RequestTransferAmount();
}
public class TransferTransaction : ITransaction
{
private TransferUI transferUI;
public TransferTransaction(TransferUI ui)
{
transferUI = ui;
}
public virtual void Execute()
{
/*code*/
transferUI.RequestTransferAmount();
/*code*/
}
}
public interface UI : IDepositUi, WithdrawalUI, TransferUI
{
}
As far as i understand this, in order to use the previous design we should have something like:
UI impui = new IMPLEMENTATIONUI(); // Some UI implementation
DepositTransaction dt = new DepositTransaction(Gui);
dt.Execute();
Now, wouldn't we need that the IMPLEMENTATIONUI implements every single method? And if so, wouldn't it break the SRP?.
Don't we use interfaces to express common behaviour among not so (or not) related abstractions?
Yes, in SOLID, interfaces are required to express common behavior. Your Transaction interface is a superb example of this. Both the DepositTransaction and WithdrawlTransaction classes depend on it. ISP (Interface Segregation Principle) wants you to split this out because you may have a need to pass a Transaction object into a function to execute it. All of the SOLID principles are designFor example:
void ExecuteTransaction(Transaction transaction)
{
transaction.Execute();
}
Please note that this method does not depend on anything but the Transaction interface. This is dependency inversion.
If you do not create this interface you would need to create two different methods for executing a WithdrawlTransaction or a DepositTransaction; instead, you can use the ExecuteTransaction method and pass in anything that implements Transaction.
ExecuteTransation(withdrawl_TransactionObject);
or
ExecuteTransaction(deposit_TransactionObject);
or later in the future:
ExecuteTransaction(unanticipatedNewTypeOf_TransactionObject);
Now, wouldn't we need that the IMPLEMENTATIONUI implements every single method? And if so, wouldn't it break the SRP?
The Implementation UI is probably what the user uses to interact with the software. The user won't have a Single Responsibility, theoretically he/she will have to use all the interfaces that are required for the IMPLEMENTATIONUI class.
I doubt the implementation UI would implement all of the interfaces but it would likely use all of these interfaces in order to execute transactions. To paraphrase "Uncle Bob" Solid Principles your user interface should be full of Volatile code while your interfaces should be the most non-volatile.
Is having one interface inherit from three others an ISP violation?
public interface UI : IDepositUi, WithdrawalUI, TransferUI
{
}
The answer is that we can't tell. It depends on whether or not the client depends on the entire interface. If it does then this is not an ISP violation. If the client doesn't depend on all three inherited interfaces then this is a violation and the client should just depend on whichever interface(s) it does need.
It might, as you observed, violate some other principle, but that would be outside of the scope of discussing the ISP. But I don't think the point is that you should create that combined interface. The point is that you can while still preserving the smaller, segregated interfaces.
We might be tempted to create on giant interface and one giant class just because one client depends on all three interfaces. But if we do that, another client that only needs withdrawals or transfers would be forced to depend on the larger interface that it doesn't need.
In real life this sort of thing grows out of control because someone starts off with broad, vaguely named interface like ITransactionService and before you know it more developers throw the kitchen sink into it. In the example the interfaces are more specifically named. That won't enforce keeping them segregated, but it helps. Giving them such specific names up front communicates what should or shouldn't be in them. It suggests a developer who planned up front to keep interfaces segregated.
As we know there are basically two important difference between Interface and Abstract class.
We can have function definitions in abstract class. This is advantageous when we want to add a function in a class without need to track down it's all implementations.
We can have multiple interface implementation.
I just came to know that we can differentiate between them in terms of Decoupling?
Your comments...
Also if you can you provide a very basic link that explains the Decoupling for Interface and Abstract class ?
We normally use Business Logic Layer, Data Access Layer(contains abstract functions) and DataAccess.SqlServer Layer. Right? Despite of the fact that we aware of the Business needs, why are we creating Data Access Layer(contains abstract functions), Why can't Business Logic layer directly access DataAccess.SqlServer Layer?
Decoupling
In programming and design, this is generally the act of making code which is re-usable with as few dependencies as possible.
Factory Pattern In This Context
When using the Factory Pattern, you have a centralized factory which can create objects without necessarily defining them itself. That would be up to the object's definition.
Abstract and Interface
Interface
Defining an interface is best practice, as it allows for a light weight type to be used for inference, and also provides a blueprint which all inheriting classes must abide by. For example, IDisposable must implement the Dispose method. Note that this is decoupled from the interface, as each class inheriting IDisposable will define its own function of the Dispose method.
Abstract
Abstract is similar to interface in that it is used for inheritance and inference, but it contains definitions which all classes will inherit. Something to the extent of every automobile will have an engine so a good abstract class for automobile could include a predefined set of methods for an engine.
Edit
Explanation
Here you will see a simple example of inheritance using an interface and an abstract class. The decoupling occurs when the interface is inherited by an abstract class and then it's methods are customized. This allows for a class to inherit the abstract class and still have the same type as the interface. The advantage is that the class inheriting the abstract class can be used when the expected type is the original interface.
Decoupling
That advantage allows for any implementation to be used which conforms to the expected interface. As such, many different overloads can be written and passed in. Here is an example of one.
Example
Interface Definition
public interface IReady
{
bool ComputeReadiness();
}
Inheritance
public abstract class WidgetExample : IReady
{
public int WidgetCount { get; set; }
public int WidgetTarget { get; set; }
public bool WidgetsReady { get; set; }
public WidgetExample()
{
WidgetCount = 3;
WidgetTarget = 45;
}
public bool ComputeReadiness()
{
if (WidgetCount < WidgetTarget)
{
WidgetsReady = false;
}
return WidgetsReady;
}
}
public class Foo : WidgetExample
{
public Foo()
{
this.WidgetTarget = 2;
}
}
public class Bar : IReady
{
public bool ComputeReadiness()
{
return true;
}
}
Decoupling
public class UsesIReady
{
public bool Start { get; set; }
public List<string> WidgetNames { get; set; }
//Here is the decoupling. Note that any object passed
//in with type IReady will be accepted in this method
public void BeginWork(IReady readiness)
{
if (readiness.ComputeReadiness())
{
Start = true;
Work();
}
}
private void Work()
{
foreach( var name in WidgetNames )
{
//todo: build name
}
}
}
Polymorphism
public class Main
{
public Main()
{
//Notice that either one of these implementations
//is accepted by BeginWork
//Foo uses the abstract class
IReady example = new Foo();
UsesIReady workExample = new UsesIReady();
workExample.BeginWork(example);
//Bar uses the interface
IReady sample = new Bar();
UsesIReady workSample = new UsesIReady();
workSample.BeginWork(sample);
}
}
I've been looking through the answers, and they all seem a little complicated for the question. So here is my (hopefully) simpler answer.
Interface should be used when none of the implementation details are available to the current scope of the code.
Abstracts should be used when some of the implementation details are available to you
And, for completeness, when all of the implementation details are available you should be using classes.
In terms of decoupling, while I somewhat agree with Shelakel, for the purposes of this question, and stating fully decoupled design practices, I would suggest the following:
Always use Interfaces to define external behaviour.
When you have some of the implementation details available, use
abstract classes to define them, but implement the interfaces on
the abstract classes, and inherit from those classes in turn.
This ensures that later if you need to change some obscure implementation detail in a new implementation you are able to do so without modifying the existing abstract class, and are also able to group different implementation types into different abstract classes.
EDIT: I forgot to include the link :)
http://www.codeproject.com/Articles/11155/Abstract-Class-versus-Interface
Abstract classes and interfaces are not MUTUALLY EXCLUSIVE choices. I often define both an Interface and an abstract class that implements that interface.
The interface ensure the maximum decoupling because it doesnt force your class to belong to a specific inheritance hierarchy, so your class may inherit from whichever other class. In other terms any class can inherit from an Interface, while classes that already inherits from other classes cannot inherit from an abstract class.
On the other side in an abstract class you can factor out code that is common to all implementations, while with Interfaces you are forced to implement everything from the scratch.
As a conclusion, often the best solution is using BOTH an abstract class and an Interface, so one can move from re-using the common code contained in the abstract class, if possible, to re-implementing the interface from the scratch, if needed.
Decoupling for the sake of decoupling is a futile exercise.
Interfaces are meant to be used for integration where the specifics aren't required to be known to be of use (ex. SendEmail()). Common uses include components, services, repositories and as markers for IOC and generic implementations.
Extension methods with generic type constraints that include interfaces allow functionality similar to traits found in Scala with similar composability.
public interface IHasQuantity { double Quantity { get; } }
public interface IHasPrice { decimal PricePerUnit { get; } }
public static class TraitExtensions
{
public static decimal CalculateTotalPrice<T>(this T instance)
where T : class, IHasPrice, IHasQuantity
{
return (decimal)instance.Quantity * instance.PricePerQuantity;
}
}
In my opinion, abstract classes and class inheritance is overused.
SOLID design principles teach us that Liskov's substitution principle implies that class inheritance should only be used if the inherited class is substitutable for the ancestor. This means that all methods should be implemented (no throw new NotImplementedExeption()) and should behave as expected.
I personally have found class inheritance useful in the case of the Template Method pattern as well as for state machines. Design patterns such as the builder pattern are in most cases more useful than deep chains of inheritance.
Now back to your question; interfaces should be used most if not all of the time. Class inheritance should be used internally and only externally for purposes of definition, whereafter an interface should be used for interaction and the concrete implementation provided via a factory or to be injected via an IOC container.
Ideally when using external libraries, an interface should be created and an adapter implemented to expose only the functionality required. Most of these components allow to be configured beforehand or at runtime to be resolved via an IOC container.
In terms of decoupling, it is important to decouple the application from its implementations (especially external dependencies) to minimize the reasons to change.
I hope that my explanation points you in the right direction. Remember that it's preferred to refactor working implementations and thereafter interfaces are defined to expose functionality.
I'm not going to discuss what are the pros/cons of these two constructs in general, as there are enough resources on that.
However, In terms of 'decoupling' a component from another, interface inheritance is much better than abstract classes, or class inheritance in general (In fact I don't think being abstract or not does not make much difference in terms of decoupling as all abstract does is prevent the class being instantiated without a concrete implementation).
Reason for above argument is, interfaces allow you to narrow down the exposure to absolute minimum of what required by the 'dependent component', if it requires a single method interface can easily do that, or even be a marker interface without any method. This might be difficult with a base class (abstract or concrete) as it should implement all the 'common' functionality for that base. Because of this a component dependent on the 'base type' will automatically 'see' all the common functionality even it does not need them for it's purposes.
Interfaces also gives you the best flexibility as even classes inheriting from bases which have nothing in common, can still implement an interface, and be used by the component expecting that interface. Good example of this is IDisposable interface.
So, my conclusion is for decoupling concern have all your components depend on interfaces than base types, and if you find most of your classes implementing that interface has a common implementation then have a base class implementing that interface and inherit other classes from that base.
The core difference is this:
Interfaces expose zero or more method signatures which all descendants must in turn implement (otherwise code won't even compile).
Interface-exposed methods can either be implemented implicitly (every type derived from the interface has access to them) or explicitely (methods can be accessed only if you typecast the object to the interface type itself). More details and an example can be found in this question.
Abstract classes expose zero or more full-fledged methods, which descendants can either use or override, providing their own implementation. This approach allows you to define a customizable, "default" behavior. Abstract classes allows you to easily add new methods with no issues (NotImplementedException really shines when adding methods to abstract classes), whereas adding a method to an interface requires you to modify all the classes implementing it.
The final point is, that a class can implement more than one interface simultaneously.
Some real-world example might be:
A hard drive which provides both USB and LAN ports is a good demonstration of multiple interface inheritance
A Laptop which has a LED marked "bluetooth" but no bluetooth hardware on board is a good analogy of the concept of not implementing an abstract method (you have the LED, you have the little B symbol, but there's nothing under the roof).
Edit 1
Here's a MSDN link explaining how to choose between interface and classes.
Defining a contract using an abstract class means that your implementers must inherit from this abstract class. Since C# doesn't support multiple inheritance, these implementers will not be able to have an alternate class hierarchy, which can be pretty limiting for some. In other words, an abstract class basically otherwise robs the implementer of the class hierarchy feature, which is often needed to get or use some other capabilities (of a framework or class library).
Defining a contract using an interface leaves the class hierarchy free for your implementers to use any way they see fit, in other words, providing much more freedom of implementation.
From a perspective of evaluation criteria, when we talk about coupling here we can speak to concerns of three separable authors, the client using (calling) the API/contract, the definer of the API/contract, and the implementer of the API/contract; we can speak to freedom (the fewer restrictions, the better), encapsulation (the less awareness necessary, the better), and resilience in the face of change.
I would offer that an interface results in looser coupling than an abstract class, in particular, between the definer and the implementer, due to higher freedom offered the implementer.
On the other hand, when it comes to versioning, you can at least add another method to the abstract class without necessarily requiring updates to subclass implementations, provided the added method has an implementation in the abstract class. Versioning interfaces across DLL boundaries usually means adding another interface, much more complex to roll out. (Of course, this is not a concern if you can refactor all the implementations together (say, because they're all in the same DLL)).
The best way to understand and remember difference between interface and abstract class, it's to remember that abstract class is a normal class and you can do everything with abstract class that you can do with the normal class with two exceptions.
You can't instantiate an abstract class
You can have abstract method only in abstract class
Coding to interface provides reusability and polymorphism.As far as class implements interface,the interface or abstract class can be passed to parameter instead of class that implements the interface.Urs common technical problem is handled vis designing interface and abstract class and implementing it and giving subclass the specific functionality implementation.Imagine its like framework.Framework define interface and abstract class and implement it that is common to all.And those that are abstract is implemented by client according to its own requirement.
public interface Polymorphism{
void run();
Void Bark();
Energy getEnergy(Polymorphism test);
Public abstract class EnergySynthesis implements Polymorphism{
abstract void Energy();
Void Bark(){
getEnergy(){
}
void run(){
getEnergy();
}public EnegyGeneartion extends EnergySynthesis {
Energy getEnergy(Polymorphism test){
return new Energy( test);
}
MainClass{
EnegyGeneartion test=new EnegyGeneartion ();
test.getEnergy(test);
test.Bark()
.
.
.
.
.
//here in Energy getEnergy(Polymorphism test) any class can be passed as parameter that implemets interface
I've been guilty of having a 1-to-1 relationship between my interfaces and concrete classes when using dependency injection. When I need to add a method to an interface, I end up breaking all the classes that implement the interface.
This is a simple example, but let's assume that I need to inject an ILogger into one of my classes.
public interface ILogger
{
void Info(string message);
}
public class Logger : ILogger
{
public void Info(string message) { }
}
Having a 1-to-1 relationship like this feels like a code smell. Since I only have a single implementation, are there any potentially issues if I create a class and mark the Info method as virtual to override in my tests instead of having to create an interface just for a single class?
public class Logger
{
public virtual void Info(string message)
{
// Log to file
}
}
If I needed another implementation, I can override the Info method:
public class SqlLogger : Logger
{
public override void Info(string message)
{
// Log to SQL
}
}
If each of these classes have specific properties or methods that would create a leaky abstraction, I could extract out a base class:
public class Logger
{
public virtual void Info(string message)
{
throw new NotImplementedException();
}
}
public class SqlLogger : Logger
{
public override void Info(string message) { }
}
public class FileLogger : Logger
{
public override void Info(string message) { }
}
The reason why I didn't mark the base class as abstract is because if I ever wanted to add another method, I wouldn't break existing implementations. For example, if my FileLogger needed a Debug method, I can update the base class Logger without breaking the existing SqlLogger.
public class Logger
{
public virtual void Info(string message)
{
throw new NotImplementedException();
}
public virtual void Debug(string message)
{
throw new NotImplementedException();
}
}
public class SqlLogger : Logger
{
public override void Info(string message) { }
}
public class FileLogger : Logger
{
public override void Info(string message) { }
public override void Debug(string message) { }
}
Again, this is a simple example, but when I should I prefer an interface?
The "Quick" Answer
I would stick with interfaces. They are designed to be contracts for consumption for external entities.
#JakubKonecki mentioned multiple inheritance. I think this is the biggest reason to stick with interfaces as it will become very apparent on the consumer side if you force them to take a base class... no one likes base classes being thrust upon them.
The Updated "Quick" Answer
You have stated issues with interface implementations outside your control. A good approach is to simply create a new interface inheriting from the old one and fix your own implementation. You can then notify the other teams that a new interface is available. Over time, you can deprecate older interfaces.
Don't forget you can use the support of explicit interface implementations to help maintain a nice divide between interfaces that are logically the same, but of different versions.
If you want all this to fit in with DI, then try not to define new interfaces and instead favour additions. Alternatively to limit client code changes, try to inherit new interfaces from old ones.
Implementation vs. Consumption
There is a difference between implementing the interface and consuming it. Adding a method breaks the implementation(s), but does not break the consumer.
Removing a method obviously breaks the consumer, but does not break the implementation - however you wouldn't do this if you are backwards-compatibility conscious for your consumers.
My Experiences
We frequently have a 1-to-1 relationship with interfaces. It is largely a formality but you occasionally get nice instances where interfaces are useful because we stub / mock test implementations, or we actually provide client-specific implementations. The fact that this frequently breaks that one implementation if we happen to change the interface isn't a code smell, in my opinion, it is simply how you work against interfaces.
Our interface-based approach is now standing us in good stead as we utilise techniques such as the factory pattern and elements of DI to improve an aged legacy code base. Testing was able to quickly take advantage of the fact that interfaces existed in the code base for many years before finding a "definitive" use (ie, not just 1-1 mappings with concrete classes).
Base Class Cons
Base classes are for sharing implementation details to common entities, the fact they are able to do something similar with sharing an API publicly is a by-product in my opinion. Interfaces are designed to share API publicly, so use them.
With base classes you could also potentially get leakage of implementation details, for example if you need to make something public for another part of the implementation to use. These are no conducive to maintaining a clean public API.
Breaking / Supporting Implementations
If you go down the interface route you may run into difficulty changing even the interface due to breaking contracts. Also, as you mention, you could break implementations outside of your control. There are two ways to tackle this problem:
State that you won't break consumers, but you won't support implementations.
State that once an interface is published, it is never changed.
I have witnessed the latter, I see it come in two guises:
Completely separate interfaces for any new stuff: MyInterfaceV1, MyInterfaceV2.
Interface inheritance: MyInterfaceV2 : MyInterfaceV1.
I personally wouldn't choose to go down this route, I would choose to not support implementations from breaking changes. But sometimes we don't have this choice.
Some Code
public interface IGetNames
{
List<string> GetNames();
}
// One option is to redefine the entire interface and use
// explicit interface implementations in your concrete classes.
public interface IGetMoreNames
{
List<string> GetNames();
List<string> GetMoreNames();
}
// Another option is to inherit.
public interface IGetMoreNames : IGetNames
{
List<string> GetMoreNames();
}
// A final option is to only define new stuff.
public interface IGetMoreNames
{
List<string> GetMoreNames();
}
Your ILogger interface is breaking the interface segregation principle when you start adding Debug, Error, and Critical methods besides Info. Take a look at the horrible Log4Net ILog interface and you'll know what I'm talking about.
Instead of creating a method per log severity, create a single method that takes a log object:
void Log(LogEntry entry);
This completely solves all of your problems, because:
LogEntry will be a simple DTO and you can add new properties to it, without breaking any client.
You can create a set of extension methods for your ILogger interface that map to that single Log method.
Here's an example of such extension method:
public static class LoggerExtensions
{
public static void Debug(this ILogger logger, string message)
{
logger.Log(new LogEntry(message)
{
Severity = LoggingSeverity.Debug,
});
}
public static void Info(this ILogger logger, string message)
{
logger.Log(new LogEntry(message)
{
Severity = LoggingSeverity.Information,
});
}
}
For a more detailed discussion on this design, please read this.
You should always prefer the interface.
Yes, in some cases you will have the same methods on class and interface, but in more complex scenarios you won't. Also remember, that there is no multiple inheritance in .NET.
You should keep your interfaces in a separate assembly and your classes should be internal.
Another benefit of coding against interfaces is an ability to easily mock them in unit tests.
I Prefer interfaces. Given stubs and mocks are also implementations (sort of), I always have at least two implementations of any interface. Also, Interfaces can be stubbed and mocked for tests.
Further, the contract angle that Adam Houldsworth mentions is very constructive. IMHO it makes the code cleaner than 1-1 implementations of interfaces make it smelly.
I can understand why to program against an interface rather than an implementation. However, in an example like the following (I find this a lot):
public interface ISomething
{
void BlahOne(int foo);
void BlahTwo(string foo);
}
public class BaseSomething : ISomething
{
public void BlahOne(int foo)
{
//impl
}
public void BlahTwo(string foo)
{
//impl
}
}
public class SpecificSomethingOne : BaseSomething
{
public void SpecificOne()
{
//blah
}
}
public class SpecificSomethingTwo : BaseSomething
//and on..
The current example of this is the component based entity system in my game. (I have IComponent, Component, PosComponent, etc).
However, I cannot see a reason to have ISomething. The name may look nicer, but it doesn't seem to have a purpose. I can just return BaseSomething all the time.
Is there a reason to have an interface when you have a single base implementation everything uses? (I can see the use for, say, IComparable or IEnumerable)
EDIT: For a slightly different scenario (yet still related enough to not need a different question), if I assume I have this structure for everything, would there be much difference if I were to use ISomething for parameter types and variables compared to BaseSomething?
I prefer "lazy design" - extract the interface from BaseSomething when you need it. Until then, keep it simple and skip it.
Right now I can think of two reasons for having an interface when there is only one implementation:
There is another mock implementation for unit tests (i.e. there is a second implementation, although not in production code).
The interface and the implementation are defined in different class libraries. E.g. when using the Model-View-Presenter pattern, the view can reside in an .exe project that is dependent on the .dll where the presenter is implemented. Then an IView interface can be put in the .dll and the presenter's reference to the view supplied through dependency injection.
Correct answer to your question would be "It depends".
You can look at it in many different ways and it's all about perspective. When you have a concrete or abstract base class, it means your objects have something in common functionally. And derived objects are inter-related in some way or the other. Interfaces let you confirm to a functional contract only where each object implementing the interface will be responsible for the implementation.
Again, when you program again interfaces, you strictly know the capabilities of the object since it implements the given interface. And you need not worry about how each object functionally implements this.
It'd not be completely wrong, If I say
each of your objects are completely
independent when it comes to
implementing the interface ISomething, given that SpecificSomethingOne and SpecificSomethingTwo do not derive from BaseSomeThing and each implement their own ISomething.
You can refer to this answer on the same matter.
it is not really necessary but it is a better design if you want to extend your program later or you want to implement another Base-Class.
In your case I would not implement the Base-Class. The Interface only is just fine if you dont want to have a default-behaviour. If you want a default-behaviour then just write the Base-Class without an Interface
If your BaseSomething were abstract and you had implementing specific things that provider overloads to abstract methods, the only way to program to them at that point would be to the ISomething interface. However, in the example you showed, there is really no reason for ISomething unless you could have multiple base implementations.
I am new to C#. Recently I have read an article.It suggests
"One of the practical uses of interface is, when an interface reference is created that can
work on different kinds of objects which implements that interface."
Base on that I tested (I am not sure my understanding is correct)
namespace InterfaceExample
{
public interface IRide
{
void Ride();
}
abstract class Animal
{
private string _classification;
public string Classification
{
set { _classification = value;}
get { return _classification;}
}
public Animal(){}
public Animal(string _classification)
{
this._classification = _classification;
}
}
class Elephant:Animal,IRide
{
public Elephant(){}
public Elephant(string _majorClass):base(_majorClass)
{
}
public void Ride()
{
Console.WriteLine("Elephant can ride 34KPM");
}
}
class Horse:Animal,IRide
{
public Horse(){}
public Horse(string _majorClass):base(_majorClass)
{
}
public void Ride()
{
Console.WriteLine("Horse can ride 110 KPH");
}
}
class Test
{
static void Main()
{
Elephant bully = new Elephant("Vertebrata");
Horse lina = new Horse("Vertebrata");
IRide[] riders = {bully,lina};
foreach(IRide rider in riders)
{
rider.Ride();
}
Console.ReadKey(true);
}
}
}
Questions :
Beyond such extend, what are the different way can we leverage the elegance of Interfaces ?
What is the Key point that I can say this can be only done by interface (apart from
multiple inheritances) ?
(I wish to gather the information from experienced hands).
Edit :
Edited to be concept centric,i guess.
The point is, you could also have a class Bike which implements IRide, without inheriting from Animal. You can think of an interface as being an abstract contract, specifying that objects of this class can do the things specified in the interface.
Because C# doesn't support multiple inheritance (which is a good thing IMHO) interfaces are the way you specify shared behavior or state across otherwise unrelated types.
interface IRideable
{
void Ride();
}
class Elephant : Animal, IRideable{}
class Unicycle: Machine, IRideable{}
In this manner, say you had a program that modeled a circus (where machines and animals had distinct behavior, but some machines and some animals could be ridden) you can create abstract functionality specific to what is means to ride something.
public static void RideThemAll(IEnumerable<IRideable> thingsToRide)
{
foreach(IRideable rideable in thingsToRide)
ridable.Ride();
}
As Lucero points out, you could implement other classes that implement IRide without inherting from Animal and be able to include all of those in your IRide[] array.
The problem is that your IRide interface is still too broad for your example. Obviously, it needs to include the Ride() method, but what does the Eat() method have to do with being able to ride a "thing"?
Interfaces should thought of as a loose contract that guarantees the existance of a member, but not an implementation. They should also not be general enough to span "concepts" (eating and riding are two different concepts).
You are asking the difference between abstract classes and interfaces. There is a really good article on that here.
Another great advantage is lower coupling between software components. Suppose you want to be able to feed any rideable animal. In this case you could write the following method:
public void Feed(IRide rideable)
{
//DO SOMETHING IMPORTANT HERE
//THEN DO SOMETHING SPECIFIC TO AN IRide object
rideable.Eat();
}
The major advantage here is that you can develop and test the Feed method without having any idea of the implementation of IRide passed in to this method. It could be an elephant, horse, or donkey. It doesn't matter. This also opens up your design for using Inversion of Control frameworks like Structure Map or mocking tools like Rhino Mock.
Interfaces can be used for "tagging" concepts or marking classes with specifically functionality such as serializable. This metadata (Introspection or Reflection) can be used with powerful inversion-of-control frameworks such as dependency injection.
This idea is used throughout the .NET framework (such as ISerializable) and third-party DI frameworks.
You already seem to grasp the general meaning of Interfaces.
Interfaces are just a contract saying "I support this!" without saying how the underlying system works.
Contrast this to a base or abstract class, which says "I share these common properties & methods, but have some new ones of my own!"
Of course, a class can implement as many interfaces as it wants, but can only inherit from one base class.