You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@geode.apache.org by Mark Hanson <mh...@pivotal.io> on 2017/09/06 17:13:19 UTC

[Discuss] Building objects with the Factory pattern or the Builder pattern. Adding the fluent model?

Problem:

To fluent and builder model or not to fluent and builder model.... In the
native client

we use the factory model of generating objects, we are wondering if a move
to the fluent model

and the builder pattern would be better.


Background:

In designing the various types of allocators for our objects, we have
considered

whether or not use the builder and fluent patterns instead of the Factory
pattern.

The current code base is written following the factory pattern, but it
seems that

the Builder pattern is becoming more popular. Further, people are also
using the

fluent model as well.

Discussion:

The argument for the Builder pattern is that it allows greater
specification before the actual

creation of the object. For example, Factory often focuses on the
attributes

after the creation of the object. The Builder pattern allows one to set the

attributes before the creation of the object, allowing a more specific
object

to be generated. Currently code is written to the Factory pattern.

Consider the following case of connecting to a cache.

Our current pattern (Factory)

CacheFactoryPtr cacheFactory = CacheFactory::createCacheFactory();

CachePtr cache = cacheFactory->create();

cache->getDistributedSystem().Credentials(“emma”, “pizza”);

cache->getDistributedSystem().connect();

API Used:

bool DistributedSystem::Credentials(String, String)

void DistributedSystem::connect()

Cache CacheFactory::create()

Builder pattern

CacheFactory cf = new CacheFactory();

cf.Locator(“192.168.0.5”, 10334);

cf.Credentials(“emma”, “pizza”);

Cache cache = cf.Connect();

API Used:

bool Locator(String, String)

bool Credentials(String, String)

Cache Connection()


Next up we think the real direction lies in further incorporating the
fluent model



Fluent model

Cache cache = new CacheFactory()->Locator(“192.168.0.5",
10334).Credentials(“emma”, “pizza”).Connect();

API Used:

CacheFactory Locator(String, String)

CacheFactory Credentials(String, String)

Cache Connection()

Do people see value in heading this direction? Sufficient value to rewrite
the API for Geode Native for example?



Conclusion

We need input to decide the future direction. What do people think???

Re: [Discuss] Building objects with the Factory pattern or the Builder pattern. Adding the fluent model?

Posted by Kirk Lund <kl...@apache.org>.
I don't think we currently have any design directions or architectural
rules for Geode documented yet other than for GFSH. As we refactor code, we
really should be following some sort of overall design guidelines.

+1 for documenting (on the wiki) and promoting fluent style APIs in our
design guidelines going forward

On Wed, Sep 6, 2017 at 5:19 PM, Mark Hanson <mh...@pivotal.io> wrote:

> For me there is only one real challenge, not an objection as I like builder
> and fluent models as well, but there is an added challenge of debugging. it
> can effectively combine 5 lines into one, which means it is *slightly* more
> annoying to debug, and the fact that return values go away, but for a
> builder object, that shouldn't be an issue.
>
> I think moving the C++ API there in the short term is a point for
> discussion, but I like the direction.
>
> On Wed, Sep 6, 2017 at 1:56 PM, Ernest Burghardt <eb...@pivotal.io>
> wrote:
>
> > I really like the Fluent pattern as it is done in C# and Java...
> >
> > I'm not sure the juice is worth the squeeze in an existing c++ library.
> >
> > I do agree we should normalize our factory/builder patterns.
> >
> > On Wed, Sep 6, 2017 at 12:28 PM, Jacob Barrett <jb...@pivotal.io>
> > wrote:
> >
> > > Mark,
> > >
> > > I believe the real issue is that we use multiple patterns and should be
> > > converging on one pattern. We have examples of both Factory and Builder
> > > models and both with and without Fluent pattern.
> > >
> > > If the Java API is tending towards Builder model with Fluent pattern
> > then I
> > > am for that as long as this common practice in the C++ world. In my
> > > searching I don't see any strong tendency towards any one model or
> > pattern
> > > in the C++ world. The only real trick to the Fluent pattern in C++ is
> > what
> > > is the type of the return value? Is it &, *, or some smart pointer? I
> > would
> > > expect it be a ref. My only issue with this is that if the original
> > factory
> > > variable is a pointer then the operator changes, for example:
> > > prtToCachFactory->setSomething("arrow").setSomethingElse("dot");
> > >
> > > It also needs to be VERY clear in the docs is the builder could ever
> > return
> > > something other than a reference to the original instance of the
> > builder. I
> > > have seen models where it is possible so you have to do things like to
> > > guard against the return changing:
> > > auto cacheFactory = CacheFactory().setSomething().setSomethingElse();
> > > if (somethingMore) {
> > >   cacheFactory = cacheFactory.setSomethingMore();
> > > }
> > > auto cache = cacheFactory.create();
> > >
> > > If you have to do that then it because less desirable to have the
> fluent
> > > pattern because it is prone to error and less readable. We should
> > guarantee
> > > something like this will work:
> > > auto cacheFactory = CacheFactory().setSomething().setSomethingElse();
> > > if (somethingMore) {
> > >   cacheFactory.setSomethingMore();
> > > }
> > > auto cache = cacheFactory.create();
> > >
> > > -Jake
> > >
> > >
> > >
> > >
> > > On Wed, Sep 6, 2017 at 10:38 AM Darrel Schneider <
> dschneider@pivotal.io>
> > > wrote:
> > >
> > > > In the geode java apis you would create a CacheFactory (or
> > > > ClientCacheFactory), configure it fluently, and then call create at
> the
> > > > end. So even though we call them factories in the geode java apis,
> they
> > > use
> > > > the Builder pattern and also support the fluent model in that you
> could
> > > do
> > > > this:
> > > >   ClientCache cache = new  ClientCacheFactory().set("propName",
> > > > "propValue").addPoolLocator("addr", 10678).create();
> > > >
> > > >  Also in java the DistributedSystem is hidden under the Cache. So you
> > add
> > > > config to your CacheFactory and when you create it, it will also
> > connect
> > > > the DistributedSystem. It used to be that in java you had to connect
> > the
> > > > DistributedSystem first and then the Cache. Since the
> DistributedSystem
> > > is
> > > > never used apart for a Cache I think this simplification was helpful
> to
> > > > users.
> > > >
> > > > On Wed, Sep 6, 2017 at 10:13 AM, Mark Hanson <mh...@pivotal.io>
> > wrote:
> > > >
> > > > > Problem:
> > > > >
> > > > > To fluent and builder model or not to fluent and builder model....
> In
> > > the
> > > > > native client
> > > > >
> > > > > we use the factory model of generating objects, we are wondering
> if a
> > > > move
> > > > > to the fluent model
> > > > >
> > > > > and the builder pattern would be better.
> > > > >
> > > > >
> > > > > Background:
> > > > >
> > > > > In designing the various types of allocators for our objects, we
> have
> > > > > considered
> > > > >
> > > > > whether or not use the builder and fluent patterns instead of the
> > > Factory
> > > > > pattern.
> > > > >
> > > > > The current code base is written following the factory pattern, but
> > it
> > > > > seems that
> > > > >
> > > > > the Builder pattern is becoming more popular. Further, people are
> > also
> > > > > using the
> > > > >
> > > > > fluent model as well.
> > > > >
> > > > > Discussion:
> > > > >
> > > > > The argument for the Builder pattern is that it allows greater
> > > > > specification before the actual
> > > > >
> > > > > creation of the object. For example, Factory often focuses on the
> > > > > attributes
> > > > >
> > > > > after the creation of the object. The Builder pattern allows one to
> > set
> > > > the
> > > > >
> > > > > attributes before the creation of the object, allowing a more
> > specific
> > > > > object
> > > > >
> > > > > to be generated. Currently code is written to the Factory pattern.
> > > > >
> > > > > Consider the following case of connecting to a cache.
> > > > >
> > > > > Our current pattern (Factory)
> > > > >
> > > > > CacheFactoryPtr cacheFactory = CacheFactory::createCacheFactory();
> > > > >
> > > > > CachePtr cache = cacheFactory->create();
> > > > >
> > > > > cache->getDistributedSystem().Credentials(“emma”, “pizza”);
> > > > >
> > > > > cache->getDistributedSystem().connect();
> > > > >
> > > > > API Used:
> > > > >
> > > > > bool DistributedSystem::Credentials(String, String)
> > > > >
> > > > > void DistributedSystem::connect()
> > > > >
> > > > > Cache CacheFactory::create()
> > > > >
> > > > > Builder pattern
> > > > >
> > > > > CacheFactory cf = new CacheFactory();
> > > > >
> > > > > cf.Locator(“192.168.0.5”, 10334);
> > > > >
> > > > > cf.Credentials(“emma”, “pizza”);
> > > > >
> > > > > Cache cache = cf.Connect();
> > > > >
> > > > > API Used:
> > > > >
> > > > > bool Locator(String, String)
> > > > >
> > > > > bool Credentials(String, String)
> > > > >
> > > > > Cache Connection()
> > > > >
> > > > >
> > > > > Next up we think the real direction lies in further incorporating
> the
> > > > > fluent model
> > > > >
> > > > >
> > > > >
> > > > > Fluent model
> > > > >
> > > > > Cache cache = new CacheFactory()->Locator(“192.168.0.5",
> > > > > 10334).Credentials(“emma”, “pizza”).Connect();
> > > > >
> > > > > API Used:
> > > > >
> > > > > CacheFactory Locator(String, String)
> > > > >
> > > > > CacheFactory Credentials(String, String)
> > > > >
> > > > > Cache Connection()
> > > > >
> > > > > Do people see value in heading this direction? Sufficient value to
> > > > rewrite
> > > > > the API for Geode Native for example?
> > > > >
> > > > >
> > > > >
> > > > > Conclusion
> > > > >
> > > > > We need input to decide the future direction. What do people
> think???
> > > > >
> > > >
> > >
> >
>

Re: [Discuss] Building objects with the Factory pattern or the Builder pattern. Adding the fluent model?

Posted by Mark Hanson <mh...@pivotal.io>.
For me there is only one real challenge, not an objection as I like builder
and fluent models as well, but there is an added challenge of debugging. it
can effectively combine 5 lines into one, which means it is *slightly* more
annoying to debug, and the fact that return values go away, but for a
builder object, that shouldn't be an issue.

I think moving the C++ API there in the short term is a point for
discussion, but I like the direction.

On Wed, Sep 6, 2017 at 1:56 PM, Ernest Burghardt <eb...@pivotal.io>
wrote:

> I really like the Fluent pattern as it is done in C# and Java...
>
> I'm not sure the juice is worth the squeeze in an existing c++ library.
>
> I do agree we should normalize our factory/builder patterns.
>
> On Wed, Sep 6, 2017 at 12:28 PM, Jacob Barrett <jb...@pivotal.io>
> wrote:
>
> > Mark,
> >
> > I believe the real issue is that we use multiple patterns and should be
> > converging on one pattern. We have examples of both Factory and Builder
> > models and both with and without Fluent pattern.
> >
> > If the Java API is tending towards Builder model with Fluent pattern
> then I
> > am for that as long as this common practice in the C++ world. In my
> > searching I don't see any strong tendency towards any one model or
> pattern
> > in the C++ world. The only real trick to the Fluent pattern in C++ is
> what
> > is the type of the return value? Is it &, *, or some smart pointer? I
> would
> > expect it be a ref. My only issue with this is that if the original
> factory
> > variable is a pointer then the operator changes, for example:
> > prtToCachFactory->setSomething("arrow").setSomethingElse("dot");
> >
> > It also needs to be VERY clear in the docs is the builder could ever
> return
> > something other than a reference to the original instance of the
> builder. I
> > have seen models where it is possible so you have to do things like to
> > guard against the return changing:
> > auto cacheFactory = CacheFactory().setSomething().setSomethingElse();
> > if (somethingMore) {
> >   cacheFactory = cacheFactory.setSomethingMore();
> > }
> > auto cache = cacheFactory.create();
> >
> > If you have to do that then it because less desirable to have the fluent
> > pattern because it is prone to error and less readable. We should
> guarantee
> > something like this will work:
> > auto cacheFactory = CacheFactory().setSomething().setSomethingElse();
> > if (somethingMore) {
> >   cacheFactory.setSomethingMore();
> > }
> > auto cache = cacheFactory.create();
> >
> > -Jake
> >
> >
> >
> >
> > On Wed, Sep 6, 2017 at 10:38 AM Darrel Schneider <ds...@pivotal.io>
> > wrote:
> >
> > > In the geode java apis you would create a CacheFactory (or
> > > ClientCacheFactory), configure it fluently, and then call create at the
> > > end. So even though we call them factories in the geode java apis, they
> > use
> > > the Builder pattern and also support the fluent model in that you could
> > do
> > > this:
> > >   ClientCache cache = new  ClientCacheFactory().set("propName",
> > > "propValue").addPoolLocator("addr", 10678).create();
> > >
> > >  Also in java the DistributedSystem is hidden under the Cache. So you
> add
> > > config to your CacheFactory and when you create it, it will also
> connect
> > > the DistributedSystem. It used to be that in java you had to connect
> the
> > > DistributedSystem first and then the Cache. Since the DistributedSystem
> > is
> > > never used apart for a Cache I think this simplification was helpful to
> > > users.
> > >
> > > On Wed, Sep 6, 2017 at 10:13 AM, Mark Hanson <mh...@pivotal.io>
> wrote:
> > >
> > > > Problem:
> > > >
> > > > To fluent and builder model or not to fluent and builder model.... In
> > the
> > > > native client
> > > >
> > > > we use the factory model of generating objects, we are wondering if a
> > > move
> > > > to the fluent model
> > > >
> > > > and the builder pattern would be better.
> > > >
> > > >
> > > > Background:
> > > >
> > > > In designing the various types of allocators for our objects, we have
> > > > considered
> > > >
> > > > whether or not use the builder and fluent patterns instead of the
> > Factory
> > > > pattern.
> > > >
> > > > The current code base is written following the factory pattern, but
> it
> > > > seems that
> > > >
> > > > the Builder pattern is becoming more popular. Further, people are
> also
> > > > using the
> > > >
> > > > fluent model as well.
> > > >
> > > > Discussion:
> > > >
> > > > The argument for the Builder pattern is that it allows greater
> > > > specification before the actual
> > > >
> > > > creation of the object. For example, Factory often focuses on the
> > > > attributes
> > > >
> > > > after the creation of the object. The Builder pattern allows one to
> set
> > > the
> > > >
> > > > attributes before the creation of the object, allowing a more
> specific
> > > > object
> > > >
> > > > to be generated. Currently code is written to the Factory pattern.
> > > >
> > > > Consider the following case of connecting to a cache.
> > > >
> > > > Our current pattern (Factory)
> > > >
> > > > CacheFactoryPtr cacheFactory = CacheFactory::createCacheFactory();
> > > >
> > > > CachePtr cache = cacheFactory->create();
> > > >
> > > > cache->getDistributedSystem().Credentials(“emma”, “pizza”);
> > > >
> > > > cache->getDistributedSystem().connect();
> > > >
> > > > API Used:
> > > >
> > > > bool DistributedSystem::Credentials(String, String)
> > > >
> > > > void DistributedSystem::connect()
> > > >
> > > > Cache CacheFactory::create()
> > > >
> > > > Builder pattern
> > > >
> > > > CacheFactory cf = new CacheFactory();
> > > >
> > > > cf.Locator(“192.168.0.5”, 10334);
> > > >
> > > > cf.Credentials(“emma”, “pizza”);
> > > >
> > > > Cache cache = cf.Connect();
> > > >
> > > > API Used:
> > > >
> > > > bool Locator(String, String)
> > > >
> > > > bool Credentials(String, String)
> > > >
> > > > Cache Connection()
> > > >
> > > >
> > > > Next up we think the real direction lies in further incorporating the
> > > > fluent model
> > > >
> > > >
> > > >
> > > > Fluent model
> > > >
> > > > Cache cache = new CacheFactory()->Locator(“192.168.0.5",
> > > > 10334).Credentials(“emma”, “pizza”).Connect();
> > > >
> > > > API Used:
> > > >
> > > > CacheFactory Locator(String, String)
> > > >
> > > > CacheFactory Credentials(String, String)
> > > >
> > > > Cache Connection()
> > > >
> > > > Do people see value in heading this direction? Sufficient value to
> > > rewrite
> > > > the API for Geode Native for example?
> > > >
> > > >
> > > >
> > > > Conclusion
> > > >
> > > > We need input to decide the future direction. What do people think???
> > > >
> > >
> >
>

Re: [Discuss] Building objects with the Factory pattern or the Builder pattern. Adding the fluent model?

Posted by Ernest Burghardt <eb...@pivotal.io>.
I really like the Fluent pattern as it is done in C# and Java...

I'm not sure the juice is worth the squeeze in an existing c++ library.

I do agree we should normalize our factory/builder patterns.

On Wed, Sep 6, 2017 at 12:28 PM, Jacob Barrett <jb...@pivotal.io> wrote:

> Mark,
>
> I believe the real issue is that we use multiple patterns and should be
> converging on one pattern. We have examples of both Factory and Builder
> models and both with and without Fluent pattern.
>
> If the Java API is tending towards Builder model with Fluent pattern then I
> am for that as long as this common practice in the C++ world. In my
> searching I don't see any strong tendency towards any one model or pattern
> in the C++ world. The only real trick to the Fluent pattern in C++ is what
> is the type of the return value? Is it &, *, or some smart pointer? I would
> expect it be a ref. My only issue with this is that if the original factory
> variable is a pointer then the operator changes, for example:
> prtToCachFactory->setSomething("arrow").setSomethingElse("dot");
>
> It also needs to be VERY clear in the docs is the builder could ever return
> something other than a reference to the original instance of the builder. I
> have seen models where it is possible so you have to do things like to
> guard against the return changing:
> auto cacheFactory = CacheFactory().setSomething().setSomethingElse();
> if (somethingMore) {
>   cacheFactory = cacheFactory.setSomethingMore();
> }
> auto cache = cacheFactory.create();
>
> If you have to do that then it because less desirable to have the fluent
> pattern because it is prone to error and less readable. We should guarantee
> something like this will work:
> auto cacheFactory = CacheFactory().setSomething().setSomethingElse();
> if (somethingMore) {
>   cacheFactory.setSomethingMore();
> }
> auto cache = cacheFactory.create();
>
> -Jake
>
>
>
>
> On Wed, Sep 6, 2017 at 10:38 AM Darrel Schneider <ds...@pivotal.io>
> wrote:
>
> > In the geode java apis you would create a CacheFactory (or
> > ClientCacheFactory), configure it fluently, and then call create at the
> > end. So even though we call them factories in the geode java apis, they
> use
> > the Builder pattern and also support the fluent model in that you could
> do
> > this:
> >   ClientCache cache = new  ClientCacheFactory().set("propName",
> > "propValue").addPoolLocator("addr", 10678).create();
> >
> >  Also in java the DistributedSystem is hidden under the Cache. So you add
> > config to your CacheFactory and when you create it, it will also connect
> > the DistributedSystem. It used to be that in java you had to connect the
> > DistributedSystem first and then the Cache. Since the DistributedSystem
> is
> > never used apart for a Cache I think this simplification was helpful to
> > users.
> >
> > On Wed, Sep 6, 2017 at 10:13 AM, Mark Hanson <mh...@pivotal.io> wrote:
> >
> > > Problem:
> > >
> > > To fluent and builder model or not to fluent and builder model.... In
> the
> > > native client
> > >
> > > we use the factory model of generating objects, we are wondering if a
> > move
> > > to the fluent model
> > >
> > > and the builder pattern would be better.
> > >
> > >
> > > Background:
> > >
> > > In designing the various types of allocators for our objects, we have
> > > considered
> > >
> > > whether or not use the builder and fluent patterns instead of the
> Factory
> > > pattern.
> > >
> > > The current code base is written following the factory pattern, but it
> > > seems that
> > >
> > > the Builder pattern is becoming more popular. Further, people are also
> > > using the
> > >
> > > fluent model as well.
> > >
> > > Discussion:
> > >
> > > The argument for the Builder pattern is that it allows greater
> > > specification before the actual
> > >
> > > creation of the object. For example, Factory often focuses on the
> > > attributes
> > >
> > > after the creation of the object. The Builder pattern allows one to set
> > the
> > >
> > > attributes before the creation of the object, allowing a more specific
> > > object
> > >
> > > to be generated. Currently code is written to the Factory pattern.
> > >
> > > Consider the following case of connecting to a cache.
> > >
> > > Our current pattern (Factory)
> > >
> > > CacheFactoryPtr cacheFactory = CacheFactory::createCacheFactory();
> > >
> > > CachePtr cache = cacheFactory->create();
> > >
> > > cache->getDistributedSystem().Credentials(“emma”, “pizza”);
> > >
> > > cache->getDistributedSystem().connect();
> > >
> > > API Used:
> > >
> > > bool DistributedSystem::Credentials(String, String)
> > >
> > > void DistributedSystem::connect()
> > >
> > > Cache CacheFactory::create()
> > >
> > > Builder pattern
> > >
> > > CacheFactory cf = new CacheFactory();
> > >
> > > cf.Locator(“192.168.0.5”, 10334);
> > >
> > > cf.Credentials(“emma”, “pizza”);
> > >
> > > Cache cache = cf.Connect();
> > >
> > > API Used:
> > >
> > > bool Locator(String, String)
> > >
> > > bool Credentials(String, String)
> > >
> > > Cache Connection()
> > >
> > >
> > > Next up we think the real direction lies in further incorporating the
> > > fluent model
> > >
> > >
> > >
> > > Fluent model
> > >
> > > Cache cache = new CacheFactory()->Locator(“192.168.0.5",
> > > 10334).Credentials(“emma”, “pizza”).Connect();
> > >
> > > API Used:
> > >
> > > CacheFactory Locator(String, String)
> > >
> > > CacheFactory Credentials(String, String)
> > >
> > > Cache Connection()
> > >
> > > Do people see value in heading this direction? Sufficient value to
> > rewrite
> > > the API for Geode Native for example?
> > >
> > >
> > >
> > > Conclusion
> > >
> > > We need input to decide the future direction. What do people think???
> > >
> >
>

Re: [Discuss] Building objects with the Factory pattern or the Builder pattern. Adding the fluent model?

Posted by Jacob Barrett <jb...@pivotal.io>.
Mark,

I believe the real issue is that we use multiple patterns and should be
converging on one pattern. We have examples of both Factory and Builder
models and both with and without Fluent pattern.

If the Java API is tending towards Builder model with Fluent pattern then I
am for that as long as this common practice in the C++ world. In my
searching I don't see any strong tendency towards any one model or pattern
in the C++ world. The only real trick to the Fluent pattern in C++ is what
is the type of the return value? Is it &, *, or some smart pointer? I would
expect it be a ref. My only issue with this is that if the original factory
variable is a pointer then the operator changes, for example:
prtToCachFactory->setSomething("arrow").setSomethingElse("dot");

It also needs to be VERY clear in the docs is the builder could ever return
something other than a reference to the original instance of the builder. I
have seen models where it is possible so you have to do things like to
guard against the return changing:
auto cacheFactory = CacheFactory().setSomething().setSomethingElse();
if (somethingMore) {
  cacheFactory = cacheFactory.setSomethingMore();
}
auto cache = cacheFactory.create();

If you have to do that then it because less desirable to have the fluent
pattern because it is prone to error and less readable. We should guarantee
something like this will work:
auto cacheFactory = CacheFactory().setSomething().setSomethingElse();
if (somethingMore) {
  cacheFactory.setSomethingMore();
}
auto cache = cacheFactory.create();

-Jake




On Wed, Sep 6, 2017 at 10:38 AM Darrel Schneider <ds...@pivotal.io>
wrote:

> In the geode java apis you would create a CacheFactory (or
> ClientCacheFactory), configure it fluently, and then call create at the
> end. So even though we call them factories in the geode java apis, they use
> the Builder pattern and also support the fluent model in that you could do
> this:
>   ClientCache cache = new  ClientCacheFactory().set("propName",
> "propValue").addPoolLocator("addr", 10678).create();
>
>  Also in java the DistributedSystem is hidden under the Cache. So you add
> config to your CacheFactory and when you create it, it will also connect
> the DistributedSystem. It used to be that in java you had to connect the
> DistributedSystem first and then the Cache. Since the DistributedSystem is
> never used apart for a Cache I think this simplification was helpful to
> users.
>
> On Wed, Sep 6, 2017 at 10:13 AM, Mark Hanson <mh...@pivotal.io> wrote:
>
> > Problem:
> >
> > To fluent and builder model or not to fluent and builder model.... In the
> > native client
> >
> > we use the factory model of generating objects, we are wondering if a
> move
> > to the fluent model
> >
> > and the builder pattern would be better.
> >
> >
> > Background:
> >
> > In designing the various types of allocators for our objects, we have
> > considered
> >
> > whether or not use the builder and fluent patterns instead of the Factory
> > pattern.
> >
> > The current code base is written following the factory pattern, but it
> > seems that
> >
> > the Builder pattern is becoming more popular. Further, people are also
> > using the
> >
> > fluent model as well.
> >
> > Discussion:
> >
> > The argument for the Builder pattern is that it allows greater
> > specification before the actual
> >
> > creation of the object. For example, Factory often focuses on the
> > attributes
> >
> > after the creation of the object. The Builder pattern allows one to set
> the
> >
> > attributes before the creation of the object, allowing a more specific
> > object
> >
> > to be generated. Currently code is written to the Factory pattern.
> >
> > Consider the following case of connecting to a cache.
> >
> > Our current pattern (Factory)
> >
> > CacheFactoryPtr cacheFactory = CacheFactory::createCacheFactory();
> >
> > CachePtr cache = cacheFactory->create();
> >
> > cache->getDistributedSystem().Credentials(“emma”, “pizza”);
> >
> > cache->getDistributedSystem().connect();
> >
> > API Used:
> >
> > bool DistributedSystem::Credentials(String, String)
> >
> > void DistributedSystem::connect()
> >
> > Cache CacheFactory::create()
> >
> > Builder pattern
> >
> > CacheFactory cf = new CacheFactory();
> >
> > cf.Locator(“192.168.0.5”, 10334);
> >
> > cf.Credentials(“emma”, “pizza”);
> >
> > Cache cache = cf.Connect();
> >
> > API Used:
> >
> > bool Locator(String, String)
> >
> > bool Credentials(String, String)
> >
> > Cache Connection()
> >
> >
> > Next up we think the real direction lies in further incorporating the
> > fluent model
> >
> >
> >
> > Fluent model
> >
> > Cache cache = new CacheFactory()->Locator(“192.168.0.5",
> > 10334).Credentials(“emma”, “pizza”).Connect();
> >
> > API Used:
> >
> > CacheFactory Locator(String, String)
> >
> > CacheFactory Credentials(String, String)
> >
> > Cache Connection()
> >
> > Do people see value in heading this direction? Sufficient value to
> rewrite
> > the API for Geode Native for example?
> >
> >
> >
> > Conclusion
> >
> > We need input to decide the future direction. What do people think???
> >
>

Re: [Discuss] Building objects with the Factory pattern or the Builder pattern. Adding the fluent model?

Posted by Darrel Schneider <ds...@pivotal.io>.
In the geode java apis you would create a CacheFactory (or
ClientCacheFactory), configure it fluently, and then call create at the
end. So even though we call them factories in the geode java apis, they use
the Builder pattern and also support the fluent model in that you could do
this:
  ClientCache cache = new  ClientCacheFactory().set("propName",
"propValue").addPoolLocator("addr", 10678).create();

 Also in java the DistributedSystem is hidden under the Cache. So you add
config to your CacheFactory and when you create it, it will also connect
the DistributedSystem. It used to be that in java you had to connect the
DistributedSystem first and then the Cache. Since the DistributedSystem is
never used apart for a Cache I think this simplification was helpful to
users.

On Wed, Sep 6, 2017 at 10:13 AM, Mark Hanson <mh...@pivotal.io> wrote:

> Problem:
>
> To fluent and builder model or not to fluent and builder model.... In the
> native client
>
> we use the factory model of generating objects, we are wondering if a move
> to the fluent model
>
> and the builder pattern would be better.
>
>
> Background:
>
> In designing the various types of allocators for our objects, we have
> considered
>
> whether or not use the builder and fluent patterns instead of the Factory
> pattern.
>
> The current code base is written following the factory pattern, but it
> seems that
>
> the Builder pattern is becoming more popular. Further, people are also
> using the
>
> fluent model as well.
>
> Discussion:
>
> The argument for the Builder pattern is that it allows greater
> specification before the actual
>
> creation of the object. For example, Factory often focuses on the
> attributes
>
> after the creation of the object. The Builder pattern allows one to set the
>
> attributes before the creation of the object, allowing a more specific
> object
>
> to be generated. Currently code is written to the Factory pattern.
>
> Consider the following case of connecting to a cache.
>
> Our current pattern (Factory)
>
> CacheFactoryPtr cacheFactory = CacheFactory::createCacheFactory();
>
> CachePtr cache = cacheFactory->create();
>
> cache->getDistributedSystem().Credentials(“emma”, “pizza”);
>
> cache->getDistributedSystem().connect();
>
> API Used:
>
> bool DistributedSystem::Credentials(String, String)
>
> void DistributedSystem::connect()
>
> Cache CacheFactory::create()
>
> Builder pattern
>
> CacheFactory cf = new CacheFactory();
>
> cf.Locator(“192.168.0.5”, 10334);
>
> cf.Credentials(“emma”, “pizza”);
>
> Cache cache = cf.Connect();
>
> API Used:
>
> bool Locator(String, String)
>
> bool Credentials(String, String)
>
> Cache Connection()
>
>
> Next up we think the real direction lies in further incorporating the
> fluent model
>
>
>
> Fluent model
>
> Cache cache = new CacheFactory()->Locator(“192.168.0.5",
> 10334).Credentials(“emma”, “pizza”).Connect();
>
> API Used:
>
> CacheFactory Locator(String, String)
>
> CacheFactory Credentials(String, String)
>
> Cache Connection()
>
> Do people see value in heading this direction? Sufficient value to rewrite
> the API for Geode Native for example?
>
>
>
> Conclusion
>
> We need input to decide the future direction. What do people think???
>