I asked this question on SO but someone pointed out that I would be better off here. He's most likely right. So here I go!
So I just wanted an opinion. I have 2 different ways to approach the problem. Okay so I have a system that I wanna design toward the future. I have some types of objects wich takes as parameters an object implementing an Interface wich can itself contain another object Implementing another interface and so on.
In this way i have
A(InterfaceB B)->B(InterfaceC C)->C(InterfaceD D) ...
Until i get to a point where the object does not contain another one. Every interfaces implement a common interface. So I have
Parent->InterfaceB --- Parent->InterfaceC --- Parent->InterfaceD
But InterfaceD does not necessarily implement InterfaceB. Because an interface does not have only one implemention, I have multiple possible trees.
A(InterfaceB B)->B(InterfaceC C)->C(InterfaceD D)->...
and
A(InterfaceB B)->B(InterfaceC Y)->Y(InterfaceZ Z)->...
So my question is this : If i want to manage the possible trees, Am I better off using reflection to generate the possible trees on startup? Or would I be better off to hold the different trees in a xml file that I would parse on startup? I have to keep in mind that those Interface types and their implementations will keep coming on. So every time I add a new type, it has to be managed. I know both solution will work. My question is more like this : What would be the best approach to orient the system toward the future.
To add some context to the situation, here's an example of a case
All those interfaces expose an adaptor. Each adaptor may need another one to do its task. For instance, I have an adaptor wich parse some data. But then this data has to be communicated with a remote target. To do this it can use ethernet, serial port, etc... So I could have a generic parser wich takes a generic communicator. That's one of the different possibilities.
If you need some clarifications dont hesitate!
3 Answers 3
I've been giving this some thought, and I believe your approach with interfaces is counter-intuitive. If you really need this kind of flexibility, interfaces are the opposite of what you want, because interfaces establish specificity, not generality.
Unless, of course, you have a single interface that looks something like this:
public interface ICommand
{
void Execute(string command);
}
Which is actually what I suggest you do. You can make that string anything you want; no need for any additional interfaces.
If you want to make it a bit more sophisticated, you can pass XML to your command, and deserialize it to an instance of a type. You can even make it polymorphic by adding a parameter that specifies the type you want to deserialize to.
My point is that trying to specify your command interface using Interfaces is de-generalizing, which is the opposite of what you want.
-
That's exactly my case. I have the kind of interface you suggested. That is how my outputs are generated. All I know is what the output is supposed to do. But then even if we know that, we only know the starting point of the command. After that there is a bunch of step to be taken before doing the actual task. For instance we need an adaptor that will adapt to the right MCU. Then we need the means of transportation. And yea I think xml will solve the problem. If at initial configuration someone manually input the settings, then it can be serialized in a xml file.Charles– Charles2013年09月26日 00:44:47 +00:00Commented Sep 26, 2013 at 0:44
-
Since you seem to be the first to have suggested, I'll accept this answer. BUT! For everyone that would be stuck in my situation, also read the one Mike Brown posted. In my opinion both are worth a read, are exellent suggestion and could solve the problem at handCharles– Charles2013年09月26日 00:53:02 +00:00Commented Sep 26, 2013 at 0:53
I think you're thinking about it in too much of a top down matter. This is a signal processing problem. The route I'd follow is to have a message bus that your inputs (or let's call them producers) send messages to and that your adaptors (or consumers) listen to. Your consumers can be responsible for transforming the messages so that another consumer can understand it. To make it highly adaptable, the consumers should be responsible for one thing and one thing only. So one consumer would be responsible for transforming a message, another would be responsible for taking a specific message and generating output.
A great book to read for pointers on how to create such a system would be Enterprise Integration Patterns.
-
As mentionned on the other post, your solution sounds quite good. Sadly I can only accept one answer.Charles– Charles2013年09月26日 00:55:16 +00:00Commented Sep 26, 2013 at 0:55
I will answer your question with a question. Why do you need to manage the trees in such a way that you need to know what contains what?
The point of interfaces is to set up an abstract contract where the user doesn't need to know what the object does and how it does it. All the user needs to know is the interface. Knowing what is contained in what violates the boundaries of the object.
The system should be able to unroll itself at the end without you needing to know the specific details of what contains what.
-
1Actually it's been answered in the hundreds of comments after the question. But there's so many its normal you havent read it. The goal of the system is to integrate many different systems together. I don't know in advance what the inputs are going to be. Neither are the outputs. So this chain of interface let's me make some very generic objects that can be used in any way. All that is required is to chain the right ones to obtain the desired output. So just like the example in the question, if the goal is to remote, attach the serial port adaptor, or Wifi if thats what is requiredCharles– Charles2013年09月22日 18:55:09 +00:00Commented Sep 22, 2013 at 18:55
Explore related questions
See similar questions with these tags.
I have a system that I wanna design toward the future
- well, there's your problem. You obviously don't know what you're going to need in the future, otherwise you would have been specific and said "I need to design for {specific thing}" and not "design toward the future". Either find out what you really need this thing to do, preferably with prototyping, A/B testing and a fast release cycle... or just design it to be simple until you understand the market better.