I am currently refactoring my code so that all important classes implement an interface (for unit testability). I came across a class that implements IComparable (non-templated); something like:
public MyClass : IComparable
{
public int CompareTo(object obj)
{
MyClass cObj = obj as MyClass;
if (cObj == null) { throw new ArgumentException(); }
// etc.
}
}
I'm wanting to interface it out, and use generics while I'm at it; something like this:
public IMyClass : IComparable<IMyClass>
{
// Other methods here
}
public MyClass : IMyClass
{
public CompareTo<IMyClass>(IMyClass other)
{
...
}
// Other methods here
}
But then, ideally, MyClass should implement IComparable<MyClass> (and then subclasses of MyClass should implement IComparable<MySubClass>).
All of this to ask several questions:
What do you think of the approach I described? Is there a better way of doing this refactoring? Is there a point in making MyClass also implement IComparable<MyClass>, or is that pointless since we already implement IComparable<IMyClass>? Any pro-tips or "best"-practices I could be made aware of?
Does it really make sense to have several objects of different types that are all comparable to each other? The language allows this, but I can count on 0 hands the number of times I've had to use it.
I'd recommend using IClass without being IComparable, and just have the derived classes implement IComparable.
P.S. I'm also against adding interfaces "for unit testability". If your program design calls for a factory pattern with interface-only coupling, then by all means code up that level of complexity. But don't abuse the design just to make your tests easier; use Moles instead.
Short answer: it depends.
In your specific example, I would say it is almost always the wrong thing to do to create an unnecessary interface (IMyClass in this case) because it just creates work for you. Rule of thumb: use interfaces only when more than one class implements them. And as you point out this particular interface doesn't even accomplish the goal of making your class directly comparable.
As far as which classes should implement IComparable, generic or otherwise, it depends entirely on what your comparison needs are. If comparison is always done between references to the base class, the derived class doesn't need to implement the interface as it will never be called.
Related
Assume this hypothetical situation:
I have a hierarchy of classes:
public class MyBase : System.Windows.Forms.TreeNode
{
public virtual void Init() {...}
}
Now I want to allow third parties to use MyBase to develop their derived classes like these:
public class Drv1 : MyBase { public override void Init() {...} }
public class Drv2 : MyBase { public override void Init() {...} }
I want my application be able to use Drv1 and Drv2 as plug-ins.
Now, my questions are:
Is it incorrect (or bad practice) to use classes (instead of interfaces) to set up plug-in mechanism?
Did I make a mistake I didn't use interfaces to provide THIRD-PARTIES with an interface? (because I want to persuade others to develop plug-ins for my app)
If answer of question 2 is YES, how could I use interfaces (because MyBase is derived from TreeNode) ? (this answer is critical for me)
Many thanks in advance.
Im using following rules:
If there is any code required in base then go for class.
If you need only structure or you need to "inherit" more than one class, use interfaces.
If you need both, features and multiple inheritance use both.
Its really depends what you do with that classes later on.
In your case you should be using base class as virtual method has some code in it, and you inherit from class that is 3rd party for you.
But once your business classes should use different implementation of that class then its worth of adding interfaces and use it in IoC or something.
I think going for Interfaces for only sake of it is not correct approach.
Is it incorrect (or bad practice) to use classes (instead of interfaces) to set up plug-in mechanism?
Neither C# or .NET has anything that labels this as incorrect. They describe under what circumstances your code will continue to work, and when it won't. Bad practice is a matter of opinion, but there are advantages and disadvantages to both approaches.
If answer of question 2 is YES, how could I use interfaces (because MyBase is derived from TreeNode) ? (this answer is critical for me)
If your callers need to provide a type that is derived from TreeNode, and you wish to use an interface, then you can.
public interface IMyInterface {
void Init() {...}
}
You cannot require classes implementing IMyInterface to derive from TreeNode, but you do not need to: you can ensure that the only way this gets exposed to your own application is via a generic registration method, where the generic type constraints do force the type to both derive from TreeNode and implement this interface:
public void RegisterTreeNode<T>() where T : TreeNode, IMyInterface {...}
If plugins are able to call RegisterTreeNode<Drv1>(), you're assured at compile time that it's going to match your requirements. You may of course use a different method signature, possibly one that deals with individual instances of the TreeNode class, it's the type constraints that are key here. If a caller attempts
class X : IMyInterface { public void Init() {...} }
and then
RegisterTreeNode<X>();
the compiler will simply reject this. The plugin may create instances of this X itself, but if your application never sees them, they cannot cause any harm.
Then third parties can do:
public class Drv1 : TreeNode, IMyInterface { ... }
public class Drv2 : TreeNode, IMyInterface { ... }
or even
public class Drv3 : SuperTreeNode, IMyInterface { ... }
where SuperTreeNode is derived from the standard TreeNode.
This is probably the main benefit of using an interface here: it's compatible with existing classes which provide additional functionality on top of the standard TreeNode.
This cuts both ways: the main benefit of using a common base class here, rather than an interface, would be that your own code can provide additional functionality.
P.S.: Depending on what you're after, it may also be possible to decouple this, to make your base class / interface responsible for creating TreeNode objects, rather than deriving from TreeNode. The general rule that favours this approach is called "composition over inheritance", and worth reading up on. It may or may not be a good fit for your particular use case.
I have an interesting problem that I keep circling around, but I never seem to quiet find a solution.
I tend to be a defensive programmer, so I try to write code that prevents problems from happening rather than reacting to problems once they've occurred. To that end, I have the following situation. Take the following code:
public class Base {}
public Interface IBase {}
public class Derived : Base, IBase {}
public class Derived2 : Base, IBase {}
...
public class DerivedN : Base, IBase {}
public class X : Base {}
public class Y : IBase {}
I need to pass a list of objects that derive from Base and implement IBase to a collection, and I need to make sure that only objects that have both are added to the list. Additionally, there can be an arbitrary number of classes that have both, so I cannot use the derived classes as constraints.
If I make the list of type Base, then I could add a Y object. If I make it of type IBase, then objects of type X can be added (neither of which are permitted).
I could, of course create my own generic collection class that has both types and has constraints for both. But, I don't want to have to do this for all possible collection types, and it's a lot of effort to duplicate all that functionality (even if you just forward the method calls to a contained class).
I could also create a BaseWithIBase class, which derives from both Base and IBase, and use that as my collection type, but I really don't want to force another abstraction if I don't have to.
I don't want this to be a runtime check, so walking the tree and throwing exceptions is not acceptable.
Can anyone suggest a better approach to this problem?
NOTE: Base and IBase are not related, just pointing out they are both base items of different types.
EDIT:
It seems that everyone wants to insist that "you don't need to do that" and that it's "not OOP". Nothing could be further from the truth. I was attempting to remove the specific from the question to prevent these kinds of questions and comments, so I will include my real situation.
The code is an implement of a Windows Service framework, based on the .NET Frameworks ServiceProcess.ServiceBase class. I am adding my own framework on top of this, that is intended to be heavily Dependency Injection based, and highly testable.
The collection must contain objects that derive from both ServiceBase and IService. IService is my framework extension that is used in my code, and for testing. It is basically just this:
public interface IService
{
void Start();
void Stop();
}
In addition, I have a number of other interfaces:
public interface IRestartableService
{
void Restart();
}
public interface IConfigurableService
{
void Configure();
}
etc.. etc.. and a service may look like this:
public class MyService : ServiceBase, IService, IConfigurableService {}
My code requires IService, Windows requires ServiceBase, thus both are needed because I work with IService, and windows works with ServiceBase. I only require IService, the other interfaces are optional.
You can create your own wrapper collection simply:
// TODO: Work out which collection interfaces you want to implement
public class BaseList
{
// Or use List<IBase>, if that's how you'll be using it more often.
private List<Base> list = new List<Base>();
public void Add<T>(T item) where T : Base, IBase
{
list.Add(item);
}
}
By using a generic method with both constraints, you can be sure that Add can only be called with an appropriate type argument.
You could have two methods to expose the data as IEnumerable<T> - one returning IEnumerable<IBase> (using Cast<T>) and one returning IEnumerable<Base>... that would let you use LINQ on either type, but not both at the same time of course.
I suspect you may find this awkward elsewhere, however - you may find yourself littering your code with generic methods which you wouldn't typically need. While there may well be a good reason for wanting both the class part and the interface part, it would be worth taking a step back and considering whether they're really both necessary. Is there something extra you could add to the interface so that you could do away with the class constraint, for example?
There is no good answer to your question because the design itself is not really fitting OOP as implemented in C#/.NET.
If you absolutely need a collection where each element statically provides two independent interfaces, either a wrapper collection or some wrapper class like Wrapper<TFirst, TSecond, T> : IBoth<TFirst, TSecond> would solve your problem.
Example:
public interface IBoth<TFirst, TSecond> {
TFirst AsFirst();
TSecond AsSecond();
}
public class Wrapper<T, TFirst, TSecond> : IBoth<TFirst, TSecond>
where T : TFirst, TSecond
{
private readonly T _value;
public Wrapper(T value) {
_value = value;
}
public TFirst AsFirst() {
return _value;
}
public TSecond AsSecond() {
return _value;
}
}
However the real question is why do you need that. Not to say that standard OOP model is perfect, but quite often a problem can be solved much easier if original design decisions are reviewed.
Another option is to completely ignore ServiceBase in most of the code and create a ServiceBaseAdapter for communication with the code that is not interface friendly. Such adapter can just call your interface methods when its method are called.
Try something like this:
List<object> collection = new List<object>();
foreach(var obj in collection.OfType<Base>().OfType<IBase>())
{
// Do what ever you want
}
This is a general design question. We often use interfaces to decouple components, write to an interface not an implementation etc. Sometimes interfaces are used w/ a basic injection technique, such as,
interface IMyInterface
{
void DoSomething();
}
static class IMyInterfaceFactory
{
public static IMyInterface GetInstance()
{
return new MyInterfaceInstance();
}
}
class IMyInterfaceConsumer
{
IMyInterface mInterface;
public IMyInterfaceConsumer()
{
this.mInterface = IMyInterfaceFactory.GetInstance();
}
public void UseTheInterface()
{
this.mInterface.DoSomething();
}
}
My question is about using the var keyword instead. Not even using a true C# interface, but still creating an 'interface', in the design sense,
static class IMyInterfaceFactory
{
// of course, this doesnt need to be a single instance
static MyInterfaceInstance mSingleInstance;
// no longer programming to the interface, just returning the instance
public static MyInterfaceInstance GetInstance()
{
// null coalesce
return mSingleInstance ?? (mSingleInstance = new MyInterfaceInstance());
}
}
class IMyInterfaceConsumer
{
public void UseTheInterface()
{
// shorthand way, could also omit var, too
var myInterface = IMyInterfaceFactory.GetInstance();
myInterface.DoSomething();
}
}
This way I still only need to change the factory once, and as long as whatever instance it returns supports the methods that need to be consumed, it will work. The advantage however is that the producing and consuming objects dont need to even know about any explicit interface, none exists. It could also cleanly support an interface with more than just a couple methods (prevent bloated interface declarations).
One obvious downside is that everytime you want to consume a method from the 'interface', the factory will potentially have to re-instantiate the class, unless there is a single instance cached (as above) or some memoization technique used.
Pros/cons of this approach? Is this a common practice?
There is nothing dynamic or loose about the var keyword. It triggers static type inference at compile time.
Your second piece of code behaves identically to
public void UseTheInterface()
{
// shorthand way, could also omit var, too
MyInterfaceInstance myInterface = IMyInterfaceFactory.GetInstance();
myInterface.DoSomething();
}
The factory function is still strongly typed. In fact, by removing the interface, you've made consumer code much more tightly coupled.
Var keyword is still technically strongly typed, so your code does know what class/interface it is. If you planned on dumping it into an object then we are saying that the rest of your code has no clue what is coming out of that factory. I wouldn't suggest that though since that causes you to cast that object to utilize anything in it.
I'm not sure where you are trying to go with the "prevent bloated interface declarations" but you could do polymorphism through extending a base class or an abstract class as well. That would make it so any code that is common between the child classes could be left alone and any specific code (methods or properties) for each child class could be overridden.
If you are looking to change out the interface all together you will need to implement an interface in the interface, see this post. So you will basically have interface A only have the method DoStuff() and other interfaces that inherit from this interface could be used polymorphically like you are describing.
interface A
{
DoStuff();
}
interface B : A
{
DoSomethingElse();
}
class C : B
{
DoStuff(){}
DoSomethingElse(){}
}
By the way, your "single instance cached" code above is close to something called a singleton pattern.
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.