Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Fluent interface

1 view
Skip to first unread message

Federico Degrandis

unread,
Jan 1, 2010, 11:15:20 AM1/1/10
to
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

Peter Duniho

unread,
Jan 1, 2010, 5:29:20 PM1/1/10
to
Federico Degrandis wrote:
> 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

Federico Degrandis

unread,
Jan 1, 2010, 9:01:23 PM1/1/10
to
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!

"Peter Duniho" <no.pet...@no.nwlink.spam.com> ha scritto nel messaggio
news:OaykdHzi...@TK2MSFTNGP06.phx.gbl...

Peter Duniho

unread,
Jan 1, 2010, 11:51:31 PM1/1/10
to
Federico Degrandis wrote:
> 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.

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

Federico Degrandis

unread,
Jan 2, 2010, 10:29:30 AM1/2/10
to
> 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

"Peter Duniho" <no.pet...@no.nwlink.spam.com> ha scritto nel messaggio

news:eR59Bd2i...@TK2MSFTNGP06.phx.gbl...

Peter Duniho

unread,
Jan 2, 2010, 2:21:28 PM1/2/10
to
Federico Degrandis wrote:
>> 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?

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

Federico Degrandis

unread,
Jan 3, 2010, 2:39:22 PM1/3/10
to
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


"Peter Duniho" <no.pet...@no.nwlink.spam.com> ha scritto nel messaggio

news:eoTvJD#iKHA...@TK2MSFTNGP04.phx.gbl...

Peter Duniho

unread,
Jan 3, 2010, 3:49:29 PM1/3/10
to
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 Degrandis wrote:
> 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?

>> 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

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

Federico Degrandis

unread,
Jan 3, 2010, 4:52:26 PM1/3/10
to
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

"Peter Duniho" <no.pet...@no.nwlink.spam.com> ha scritto nel messaggio

news:ePCf$YLjKH...@TK2MSFTNGP02.phx.gbl...

Peter Duniho

unread,
Jan 4, 2010, 6:35:57 PM1/4/10
to
(Sorry�I posted this yesterday, but my news server appears to have lost
it. It failed to show up even on my own server, never mind any others,
as near as I can tell).


Federico Degrandis wrote:
> [...]


>> 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

The question remains: why is it (now) in the Feature class? And how
does the Feature class (now) know of Sensor instances you've retrieved
from the Bus?

> 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)

So, each instance of Feature is examining the same data other instances
of Feature are examining, but performing its own custom processing on
the data. Correct?

If so, then that tells me that GetResults() � which you've said
initiates data flow � definitely should _not_ be in the Feature class.
A Feature should be attached to whatever data input is appropriate
(filtered component data, perhaps?), and should only examine that data
when it's delivered.

Delivery should be automatic, pushed through some kind of data flow
graph, when the Bus is moving data.

> It exists because a feature is an algorithm so I'm going to create a
> specific Feature class for each feature

IMHO, it seems to me that a Feature is really just a special case of a
Filter. That is, presumably a Filter takes some input and transforms
it. Probably in the case of the Filter, the data's format remains the
same, but technically there's no reason that _has_ to be true. So a
Feature can be thought of as a Filter that does a more elaborate
transformation on the data.

So instead of something simple, like scaling xyz acceleration
information, with the output still being xyz acceleration information,
just with different values, you could get some sort of feature
information (position, behavior, etc.) from the acceleration input.

Of course, the other big difference is that presumably your simpler
Filter class takes only one input, while a Feature would have multiple
inputs. But again, that's just a difference in degree. If you think of
filters as being things that take one _or more_ inputs, then it becomes
more clear that a Feature is really just a more sophisticated Filter.

A final difference in the Feature from a normal Filter is that it
probably has no data flow output. Just some kind of way to signal that
the feature being tested for is present. But again, that's just an
abstraction detail, if you think of any filter has being able to have
zero _or more_ outputs.

(For that matter, if you think of a filter as being able to have zero or
more _inputs_, then even your Bus could be considered a kind of "source
filter", and of course something like a Sensor or Component could also
be a filter, depending on their exact relationship to the Bus or Sensor,
respectively).

(Oh, and anyone reading along and who is familiar with DirectShow may
recognize a lot of this�I'm borrowing heavily from its design in this
discussion, as in a lot of ways DirectShow is just a way of moving and
transforming data through a graph :) )

Perhaps this abstraction will help simplify your overall design.

>> 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.

But what does "extract a feature" mean? What implication does that have
in code?

Based on your description so far, I would think something along these
lines would make sense:

Bus --- Sensor1 --- Component1.1 --- Filter1.1.1 --- Out1.1.1
| |
| --- Component1.2 --- Filter1.2.1 --- Out1.2.1
|
--- Sensor2 --- Component2.1 --- Filter2.1.1 --- Out2.1.1
|
(etc.)

Where the graph continues like so:

+----------+
Out1.1.1 ---| |
| FeatureA |--- Signal
Out2.1.1 ---| |
+----------+

+----------+
| |
Out1.2.1 ---| FeatureB |--- Signal
| |
+----------+

And the "Signal" for a Feature could just be a C# event, raised when the
data presented to a Feature matches the requirements expected for that
Feature.

Each Feature would be constantly monitoring data presented it, just as
any Filter would, as long as data is flowing through your object graph.
You can manage the flow however you like; I think an event-driven (as
in C# events) push model would work well, but I don't really know enough
about the system to be able to have an informed opinion.

If using C# events to push data through the graph, I would use the event
itself to present the data, rather than the more common .NET paradigm of
using an event to signal that a property has changed and should be
inspected (actually, .NET does have examples of the former�it's just
that the latter is seen much more often).

In a system like this, the method you currently seem to be calling
GetResults() would instead be named something more indicative of the
on-going nature, such as RunGraph(), or maybe even just Run(). Of
course, you'd need something to stop the data flow, unless it naturally
stops on its own somehow.

>> 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.

How does a sensor know to retrieve the data? Your statement implies a
pull model, but pull works best when you've got a data source that's a
predefined stream, and can deliver data as often as a downstream object
needs it. From your description, it sounds as though you're dealing
with real-time data, available only briefly and at exactly the moment
it's generated. As I mentioned, I can't really have an informed
opinion, but it sure _sounds_ like it would work better using a push model.

> [...]


>> 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)

How does a Feature that needs data from multiple Sensors deal with the
thread synchronization issues? On what thread does a Feature run? Does
it have its own thread too? Given that you can get a Component, doesn't
that mean that you can further demux a Sensor data stream into
individual Component data streams? Is there a separate thread for each
of those data streams too? If not, how are they handled?

> [...]


>> 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.

Does GetSensor() create a new instance of Sensor? Or are these
instances that already exist, and which Feature is already aware of
prior? If not the latter, then how would a GetResults() method in the
Feature class have any way to cause the threads for each Sensor to start?

> 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)

Does the Bus not already know what data goes with what Sensor? I would
think that the Bus should be some sort of aggregator/controller, with
inputs on one side (probably representing real hardware?), pulling all
those inputs together, and then distributing them as appropriate to the
software abstraction on the other side in the form of the Sensor instances.

But each Sensor instance should only have to deal with the data specific
to it, right? Wouldn't the Bus take care of directing the data as
appropriate? Or does only each Sensor know how to recognize its data?

> [...]


> 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.

I would prefer no email. However, you can post an image online if you
think it would be helpful, and include the link to that image in a
newsgroup post. That way, if anyone else is following along, they can
see it too. Otherwise, you can try ASCII graphics. As you can see from
mine above, they don't need to be good so long as they get the point
across. :)

Pete

0 new messages