geode-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mark Hanson <mhan...@pivotal.io>
Subject Re: [Discuss] Building objects with the Factory pattern or the Builder pattern. Adding the fluent model?
Date Thu, 07 Sep 2017 00:19:04 GMT
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 <eburghardt@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 <jbarrett@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 <mhanson@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???
> > > >
> > >
> >
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message