How it works "Programming on interfaces"?

I like the idea of โ€‹โ€‹"programming interfaces" and avoiding the use of a "new" keyword.

However, what should I do when I have two classes that have the same interface but are fundamentally different for customization. Without going into details about my specific code, I have an interface with the "DoStuff" method. This class implements two classes. One of them is very simple and does not require any initialization. The other has five different variables that need to be configured. In combination, they allow literally millions of ways the class works when calling DoStuff.

So when do I โ€œnewโ€ these classes? At least Iโ€™m talking about using factories, but I donโ€™t think that they are suitable in this case because of the huge difference in settings. (By the way: there are about ten different classes on the interface, each of which allows you to form part of a complex pipeline and each with different configuration requirements).

+4
source share
5 answers

I think you may not understand the concept of programming for interfaces. You should always use the new keyword in object-oriented languages โ€‹โ€‹to create new instances of objects. Just because you program on interfaces, this does not eliminate this requirement.

Programming on an interface simply means that all of your specific classes have their own behavior defined in the interface, and not in the particular class itself. Therefore, when you determine the type of a variable, you define it as an interface instead of a specific type.

In your case, just implement DoStuff in your specific classes, since each class needs to be implemented (whether it is simple or with 10 other initialized objects and settings). For example, if you have an IInterface interface and a class SomeClass that implements IInterface . You can declare an instance of SomeClass as such:

 IInterface myInstance = new SomeClass(); 

This allows you to pass this instance to other functions without requiring these functions to worry about the implementation details of this instance class.

+6
source

You really have 3 options. Use a new one, use a factory, or use a DI container. With the DI container, your five variables should most likely be in the roles configuration file.

But to be completely honest, it looks like you are making your life harder than necessary by forcing yourself into a corner. Instead of coding some kind of ideal, but rather code in a way that best facilitates solving the problem. Not to mention that you have to hack it, but actually, saying that you don't want to use the new one, it really makes your life harder than it should be ...

+2
source

No matter what you use, at some point you will have to instantiate your classes to use them, there is no way.

How to do this depends on what you want to do and the semantics of these classes.

Take the class you mentioned in these fields.

Can these fields be read somewhere? Configuration file for example? If so, perhaps all you need is just a default constructor that initializes these fields from such a configuration file.

However, if the contents of these fields really need to be transferred from the outside world, there is no way around this.

Perhaps you should look at the IoC container and dependency injection?

+1
source

If you pass many configuration parameters to your class, it may have too many responsibilities. You should study the breakdown into smaller classes in which there is only one responsibility.

Avoiding a new keyword can be valuable because it creates a dependency on the implementation class. A better solution would be to use Injection Dependancy.

eg

 public interface IDoStuff { void DoStuff(); } public class DoStuffService { private IDoStuff doer; public DoStuffService() { //Class is now dependant on DoLotsOfStuff doer = new DoLotsOfStuff(1,true, "config string"); } } public class DoStuffBetterService { private IDoStuff doer; //inject dependancy - no longer dependant on DoLotsOfStuff public DoStuffBetterService(IDoStuff doer) { this.doer = doer; } } 

Obviously, you still need to create an IDoStuff object that gets passed somewhere. A container with inverse control (IoC) is a good tool to implement this. Here's a good tutorial for Castle Windsor Container if you're interested in learning more. (There are many other IoC containers, I just use this one.)

The example in your question was very abstract, so I hope this answer is helpful.

0
source

If you understand correctly, the problem is related to another initialization. You need to provide two classes having the same interface. Nobody needs anything, while another needs some parameters and calls complex initialization.

You should use a constructor that gets an InitializationParameter. Both classes should get this. One with a simple interface that does not need it. Another who needs parameters and will get them from him.

If you are worried about initialization, you can use factory, just ask it about some interface that provides this initialization parameter, and factory will create, run and return an object to you according to the values โ€‹โ€‹you specified.

If something is unclear - ask.

0
source

All Articles