Fluent is ... faster ...

Posted by jmls on 29-Mar-2011 15:54

Smack me with a kipper.

fluent:

a = (NEW ValueObject.Address())

    :AcornCode("something")

    :Building("something")

    :Country("something")

    :County("something").

Normal

    a = NEW ValueObject.Address().

    ASSIGN a:AcornCode = "something"

           a:Building  = "something"

           a:Country   = "something"

           a:County   = "something".

1000 iterations, fluent is  120ms, normal is 155ms


Wow

All Replies

Posted by Admin on 29-Mar-2011 16:01

fluent:

 

Is that new in 10.2B04?

Posted by Peter Judge on 29-Mar-2011 16:16

And snack me because you can stack 'em with the parens ... my versions look something like (2 lines).

a = NEW ValueObject.Address().

a:AcornCode("something")

:Building("something")

:Country("something")

:County("something").

-- peter

Posted by Peter Judge on 29-Mar-2011 16:16

Fluent: http://en.wikipedia.org/wiki/Fluent_interface .

Basically each method returns THIS-OBJECT (as an Interface, say) and so you can daisy-chain them along.

-- peter

Posted by Thomas Mercer-Hursh on 29-Mar-2011 16:16

Might be even faster to supply them with the constructor.

Posted by jmls on 29-Mar-2011 16:36

I wish

No, it's just a visual "cheat" .. this (crappy) code fragment shows

how the cheat works.

class ....

METHOD PUBLIC ValueObject.Address AcornCode(p_Data AS CHAR):

AcornCode = p_Data.

RETURN THIS-OBJECT.

END METHOD.

METHOD PUBLIC ValueObject.Address Building(p_Data AS CHAR):

Building = p_Data.

RETURN THIS-OBJECT.

END METHOD.

METHOD PUBLIC ValueObject.Address Country(p_Data AS CHAR):

Country = p_Data.

RETURN THIS-OBJECT.

END METHOD.

METHOD PUBLIC ValueObject.Address County(p_Data AS CHAR):

County = p_Data.

RETURN THIS-OBJECT.

END METHOD.

end class.

have a look at http://en.wikipedia.org/wiki/Fluent_interface

Posted by Admin on 29-Mar-2011 16:36

Almost looks like a new language feature in this formatting... But now it's clear.

Posted by jmls on 29-Mar-2011 16:36

My problem with using a constructor-based approach is that the order

of the parameters is strict. This isn't. Mind you, not sure that I

like it ...

On 29 March 2011 22:16, Thomas Mercer-Hursh

Posted by Peter Judge on 29-Mar-2011 16:40

jmls wrote:

My problem with using a constructor-based approach is that the order

of the parameters is strict. This isn't. Mind you, not sure that I

like it ...

I really like it, when it's appropriate (of course). It's great for building more natural-reading constructs, as in ...

        /* scopes the tenant manager's lifecycle to the security manager's */

        oBindingSyntax = Bind('OpenEdge.CommonInfrastructure.Common.ITenantManager').

        oBindingSyntax

            :To('OpenEdge.CommonInfrastructure.Server.TenantManager')

            :Using('OpenEdge.CommonInfrastructure.Common.InjectABL.ServiceProvider')

            :InScope(Class:GetClass('OpenEdge.CommonInfrastructure.Common.InjectABL.ManagerScope'),

                     ManagerScopeEnum:SecurityManager)

            :OnServerSession().       

And now with Julian's parens-around-the-first-line trick, it'll be even easier to read.

-- peter

Posted by Admin on 29-Mar-2011 16:51

My problem with using a constructor-based approach is that the order

of the parameters is strict. This isn't. Mind you, not sure that I

like it ...

I see here two different requirements: There are cases where a constructor requires a series of parameterst o properly construct and object instance, assign some initial properties and do some initial work. In this case the constructor knows (by the sequence of code in the constructor) when those initial properties as set and when it can do the initial work.

When using an empty constructor and then either setting a hand full of properties or doing fluent method calls, the order is random, it may be easier to read, but nobody knows, when you are done setting the initial proeperies and when the initial work can start.

.NET Controls solve this using BeginInit() and EndInit() methods (support for transacted initialization). But that is a manual task and can be easily forgotten (listen, Dr. Thomas) without a code generator (like the .NET Visual Designer).

In cases when you have a constructor that requires that many parameters that you can get confused by their order, I'd rather pass a single parameter object to the constructor and take the properties of the parameter objects as the input.

Posted by Peter Judge on 29-Mar-2011 16:56

I see here two different requirements: There are cases where a constructor

requires a series of parameterst o properly construct and object instance,

assign some initial properties and do some initial work. In this case the

constructor knows (by the sequence of code in the constructor) when those

initial properties as set and when it can do the initial work.

To add to this, I see constructor arguments as being mandatory arguments (or reasonably so); state added via a method/property (whether using a fluent interface or other) is not (ie it is optional data).

-- peter

Posted by Thomas Mercer-Hursh on 29-Mar-2011 16:57

I confess that I find it a bit of a cheat and obscure.

One can get around the constructor parameter order by using a parameter object with the values.  There are a lot of places one would/should have one anyway.

This thread is closed