Fluent interface

  • Thread starter Federico Degrandis
  • Start date
F

Federico Degrandis

Hello everyone!
I should implement a kind of fluent interface I'm just a little perplexed
about how to do:

GetBus (Bus interface)
.. GetSensor (NumSens)
.. GetComponent (Name)
.. GetDimension (Name)
.. ApplyFilter (filtername)
.. ApplyFilter (filtername)
.. ApplyFeatures (FeatureName)
.. GetResults ()

These are basically methods that the user can call and have to be invoked
in this order (the ApplyFilter can called several times)

GetBus returns an instance of Bus, GetSensor instance of Sensor
GetComponent instance of Component and so on.

At first I thought to put the method GetBus inside a class
FluentFlow, GetSensor inside the Bus class and GetComponent in Sensor class.
The problem is that at the end GetResults must interact with the instance of
Bus (in order to
run some threads).

The solutions that came to my mind are:
- Use some kind of message broker where basically the class that
contains the method getResults () tells the instance of Bus to run the
thread
- Include all methods in the FluentFlow class (the problem is that they
only be called in that order)
- Create classes XXXFluentInterface managed by the FluentFlow class in order
to
handle even the order of the methods (GetBus will return BusFluentInterface
that will have a method GetSensor returning SensorFluentInterface)

Any idea?

Cheers
Federico
 
P

Peter Duniho

Federico said:
Hello everyone!
I should implement a kind of fluent interface

Why? Where does this requirement come from?
I'm just a little
perplexed about how to do:

GetBus (Bus interface)
.. GetSensor (NumSens)
.. GetComponent (Name)
.. GetDimension (Name)
.. ApplyFilter (filtername)
.. ApplyFilter (filtername)
.. ApplyFeatures (FeatureName)
.. GetResults ()

These are basically methods that the user can call and have to be invoked
in this order (the ApplyFilter can called several times)

It is not clear why the methods must be called in a particular order.
Is it that you have to have a Bus to call GetSensor()? And that you
have to have a Sensor to call GetComponent()? And that you have to have
a Component to call GetDimension()?

Or something else?

If the former, then this seems fundamentally incompatible with a fluent
interface, which presupposes that each call can return the same object
that was used to make that call.

If it's something else, then you should elaborate on why the order is
important. In general, having a specific order of operations imposed on
an interface suggests that those operations should all be encapsulated
in a single method, rather than forcing the client to comply with the
given order.
GetBus returns an instance of Bus, GetSensor instance of Sensor
GetComponent instance of Component and so on.

At first I thought to put the method GetBus inside a class
FluentFlow, GetSensor inside the Bus class and GetComponent in Sensor
class.

Whatever you do, don't include the word "fluent" in your class name.
Design patterns are implicit in the type's interface; there's no need to
put the pattern's name in the type's name itself.
The problem is that at the end GetResults must interact with the
instance of Bus (in order to run some threads).

Then it seems to me the fluent interface pattern doesn't apply.
The solutions that came to my mind are:
- Use some kind of message broker where basically the class that
contains the method getResults () tells the instance of Bus to run the
thread
- Include all methods in the FluentFlow class (the problem is that they
only be called in that order)
- Create classes XXXFluentInterface managed by the FluentFlow class in
order to
handle even the order of the methods (GetBus will return
BusFluentInterface that will have a method GetSensor returning
SensorFluentInterface)

All of the above are only "solutions" in that they shoehorn some other
design into the fluent interface pattern. Design patterns aren't there
to be forced upon the code; they exist to be used when the code already
lends itself nicely to the pattern.

Absent any other information, I'd say the real solution is to not force
the fluent interface pattern on the entirety of the code. It may well
still apply within some specific objects you have, but to try to force
the entire interface into a fluent pattern doesn't appear to be useful
in this case.

Pete
 
F

Federico Degrandis

Hi peter, thanks for reply!
I know that it's not a fluent interface or better it doesn't supply the
fluent interface pattern but I need something similar
It is not clear why the methods must be called in a particular order. Is
it that you have to have a Bus to call GetSensor()? And that you have to
have a Sensor to call GetComponent()? And that you have to have a
Component to call GetDimension()?

Yes!

I choose to use something similar to the fluent interface because it's more
simple to understand to the
developers that are going to use the library.

I need to call the methods in this order because they are processing a data
flow.

What do you suggest?

Thanks
Federico

PS: sorry for my poor english!
 
P

Peter Duniho

Federico said:
Hi peter, thanks for reply!
I know that it's not a fluent interface or better it doesn't supply the
fluent interface pattern but I need something similar


Yes!

I choose to use something similar to the fluent interface because it's
more simple to understand to the
developers that are going to use the library.

If it's not a fluent interface but you call it a fluent interface,
you're just going to confuse people.
I need to call the methods in this order because they are processing a
data flow.

What do you suggest?

It's still not clear what the issue is. You wrote above that the
particular order is because you have to call a method in one class to
get an instance of another class so you can then call the method in that
other class, etc. Given that, it seems to me that the order of calling
is automatically enforced by that requirement. What more is there to do?

Pete
 
F

Federico Degrandis

It's still not clear what the issue is. You wrote above that the
particular order is because you have to call a method in one class to get
an instance of another class so you can then call the method in that other
class, etc. Given that, it seems to me that the order of calling is
automatically enforced by that requirement. What more is there to do?

The issue is that the GetResults method (from the Feature class) has to
"say" to the Bus instance to start some operations.
How could I do?

Thanks
Federico
 
P

Peter Duniho

Federico said:
The issue is that the GetResults method (from the Feature class) has to
"say" to the Bus instance to start some operations.
How could I do?

Unfortunately, you haven't provided enough detail for me to know what
the answer to that question is. Why is GetResults() a member of the
Feature class rather than the Bus class? Can you not simply pass a
reference to an instance of the Bus class to the GetResults() method?
Could the Feature class know about the Bus instance some other way?
Alternatively, can some other code have the Bus instance start some
operations, and then pass those results to the Feature class? Are you
dealing with a strictly single-threaded implementation here, or is there
some asynchronous behavior involved?

Those are just a few of the questions that come to mind.

The question so far is very sparsely described. Too sparse for me to
see any specific answer.

Pete
 
F

Federico Degrandis

So, I have to manage a flow which comes from a bus (I have to manage two or
more kind of bus).
The flow is composed by one or more sensor data and with the GetSensor(Num)
method I get only data for the specified sensor.
Each sensor data has three or more components (Accelerometer, Magnetomer,
etc... I have to manage custom components with a
plugin system)...Then I have to apply some filter to the data components and
at the end we have the GetResults (from Feature class)
method that should start the flow or better should say to the Bus instance
to start the flow acquisition. When the flow acquisition starts
the bus class will pass the data to the Sensor instance which will extract
its data and so on.
Are you dealing with a strictly single-threaded implementation here, or is
there some asynchronous behavior involved?

I'm dealing with a multi-threaded implementation. I have one thread for each
sensor
(if the user call GetSensor(num) three times
instanceBus.GetSensor(1).....GetResults() ,
instanceBus.GetSensor(2).....GetResults() there'll be
two threads)

Thanks
Federico
 
P

Peter Duniho

It would have been helpful, to me at least, if you had answered each of
my questions, point by point. I didn't pose them rhetorically.

That said…

Federico said:
So, I have to manage a flow which comes from a bus (I have to manage two
or more kind of bus).
The flow is composed by one or more sensor data and with the
GetSensor(Num) method I get only data for the specified sensor.

I assume by "get only data for", you actually mean GetSensor(num)
returns an object representing a specific sensor, and from that object
you can get the data the sensor comprises (e.g. the "three or more
components" you mentioned).
Each sensor data has three or more components (Accelerometer,
Magnetomer, etc... I have to manage custom components with a
plugin system)...Then I have to apply some filter to the data components
and at the end we have the GetResults (from Feature class)

Again, why is GetResults() in the Feature class? What _is_ the Feature
class? Why does it even exist? What is its relationship to the other
classes?
method that should start the flow or better should say to the Bus
instance to start the flow acquisition. When the flow acquisition starts
the bus class will pass the data to the Sensor instance which will
extract its data and so on.

Does the same data come from the bus, regardless of whether you've
actually retrieved a specific Sensor object? Or does the Bus only emit
data for the Sensor objects that exist?
I'm dealing with a multi-threaded implementation. I have one thread for
each sensor
(if the user call GetSensor(num) three times

Did you really mean to write "three times"? Because the example you
give shows only two calls to GetSensor().
instanceBus.GetSensor(1).....GetResults() ,
instanceBus.GetSensor(2).....GetResults() there'll be
two threads)

Where does the data go? What consumes the data? Are the data from all
Sensor instances aggregated somehow, or is each data stream from a given
Sensor consumed individually?

I have the sense that this has nothing to do with fluent interfaces. So
hopefully, that's clear and you're not trying to make a fluent interface
any more (or at least, not for the whole thing…I suppose some subset
might be able to take advantage, such as configuring the filtering).

Besides that, calling GetSensor() really should only retrieve a Sensor
instance. It sounds from your description, it sounds like a call to
GetSensor() causes some implicit change to the Feature class (whatever
that is). But IMHO it would be better design to require the client to
make that change explicit. Side-effects in code almost always lead to
maintenance problems.

In fact, if you approach it that way, I suppose you could still make
that part of the interface fluent also. That is, whatever new method
you add to the Feature class to add a Sensor instance to its flow graph,
that could return the same Feature instance, so that, for example, your
calls might look like:

Sensor sensor1 = ...;

Feature.AddSensor(sensor1).GetResults();

There may be other places where fluency works. I just don't think
you're going to be able to, or even want to, apply the fluent interface
pattern to the entire design.

Pete
 
F

Federico Degrandis

Thanks again for your help and sorry if I haven't answered all the questions
but I was in a hurry and I missed some.
I assume by "get only data for", you actually mean GetSensor(num) returns
an object representing a specific sensor, and from that object you can get
the data the sensor comprises (e.g. the "three or more components" you
mentioned).

It's right
Again, why is GetResults() in the Feature class? What _is_ the Feature
class? Why does it even exist? What is its relationship to the other
classes?

I could insert the GetResults() method also in the Bus class

A Feature is like a behavior, when I call ApplyFeatures I tell the system to
try to recognize a
specific behavior (for example: the person is standing up, he's running,
etc)

It exists because a feature is an algorithm so I'm going to create a
specific Feature class for each feature
What is its relationship to the other classes?

I'm doing data processing and the feature extraction is the final part of
this kind of data processing, so when I extract a
feature I get a result.
Does the same data come from the bus, regardless of whether you've
actually retrieved a specific Sensor object? Or does the Bus only emit
data for the Sensor objects that exist?

The Bus class will retrieve all data available in the bus, then each sensor
will retrieve its data.
Did you really mean to write "three times"? Because the example you give
shows only two calls to GetSensor().

No, I didn't! Sorry
Where does the data go? What consumes the data? Are the data from all
Sensor instances aggregated somehow, or is each data stream from a given
Sensor consumed individually?

The feature consumes the data, and each data stream is consumed individually
in a separeted thread (a thread for each sensor)
I have the sense that this has nothing to do with fluent interfaces. So
hopefully, that's clear and you're not trying to make a fluent interface
any more (or at least, not for the whole thing…I suppose some subset might
be able to take advantage, such as configuring the filtering).

I didn't want to use the Fluent Interface pattern, I would like only to call
the methods in a similar way
(Sorry if when I've started the thread I've explained the problem badly)

Yes, I could use the Fluent Interface in the filtering part
Besides that, calling GetSensor() really should only retrieve a Sensor
instance. It sounds from your description, it sounds like a call to
GetSensor() causes some implicit change to the Feature class (whatever
that is). But IMHO it would be better design to require the client to
make that change explicit. Side-effects in code almost always lead to
maintenance problems.

Calling GetSensor(sensNum) doesn't cause any change to the Feature class,
the feature is an algorithm so it works
indifferently either on the sensor1's data either on the sensor2's data.

When I get the bus instance I can call GetSensor more times. The Bus class
will multiplex the data flow
(hence there will be more copies of the flow) and it'll pass the data to
each sensor created (calling GetSensor)

In fact, if you approach it that way, I suppose you could still make that
part of the interface fluent also. That is, whatever new method you add
to the Feature class to add a Sensor instance to its flow graph, that
could return the same Feature instance, so that, for example, your calls
might look like:

Sensor sensor1 = ...;

Feature.AddSensor(sensor1).GetResults();

There may be other places where fluency works. I just don't think you're
going to be able to, or even want to, apply the fluent interface pattern
to the entire design.

It could be an idea!!

It isn't so easy to understand, if you want I could send you an email with
an image which explains fine the whole system.

Thanks for help!
Federico
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top