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 <dschnei...@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 <mhan...@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???
> >
>

Reply via email to