0

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
    On a more serious note, this is very abstract. Without knowing what the purpose of the interfaces are, it's difficult to advise you. Consider describing the specific scenario you are using this for. Maybe we can tell you a better way to do it. – Robert Harvey Sep 21 '13 at 17:54
  • 2
    Still looks overly abstract. Are you familiar with YAGNI? What's the real world problem being solved? – Dan Pichelman Sep 21 '13 at 18:07
  • 3
    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. – Aaronaught Sep 21 '13 at 18:18
  • 2
    You are wrong. The objective of your system is to help users accomplish a specific task. If your users are programmers and the task they want to accomplish is to build their own signal/message-processing system, then perhaps the function of your system might be to "take generic input and produce generic output", however unlikely. If that's not a 100% accurate description of your domain, then you are simply passing the buck with respect to requirements analysis. There are plenty of workflow engines around, and people generally only use them when supporting multi-tenant SaaS apps. – Aaronaught Sep 21 '13 at 19:05
  • 2
    I learned a new word today "domotic". Since this is home automation for your place, you are the user. You have a finite set of inputs, a finite set of outputs, and a single source of specifications. Design something that can be built in a couple of months, expect it to work for a few (5 - 8) years, then repeat the process. Technology advances so fast that the extra effort you put into "future proofing" will be wasted. Roll with it. – Dan Pichelman Sep 21 '13 at 20:14
0

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 Sep 26 '13 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 hand – Charles Sep 26 '13 at 0:53
0

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 Sep 26 '13 at 0:55
-3

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.

  • 1
    Actually 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 required – Charles Sep 22 '13 at 18:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.