RE: Re: Factory Method Pattern via Inner Classes
Subject: RE: Re: Factory Method Pattern via Inner Classes
Newsgroups: gmane.comp.programming.domain-driven-design
Date: 2008-08-07 19:20:41 GMT
Hi Aaron,
Nice to meet you. It occurred to me too late, after my last reply in this thread, that I should have mentioned that I’ve appreciated your posts here recently; they have been insightful.
Turns out the pattern was named Constructor Method in the published Smalltalk Best Practice Patterns book (it was named Complete Creation Method in an earlier manuscript of the book, and in earlier works of Kent Beck).
The complexity involved in creating a valid (for some use) instance of a class seems to drive where and how to encode the creation logic, with the choices being simple constructors, Factory Methods, or Factory classes. With the latter two choices, there is an additional decision as to where to “site” the Factory, to use Eric’s nice wording. As an old Smalltalker, I’m accustomed to putting Factory Methods on the class of the created object (in the case of Complete Creation Methods), and on Aggregate Roots aggregating created objects e.g. OrderLineItem newLineItem(Product) on an Order class. The original GoF Factory Method pattern description describes the general case of a Factory Method on a class which may be different than that of the created object.
When the complexity involved in creating a valid instance of a class is sufficient enough that a separate Factory class is warranted, it would make sense to me to use an inner class, for the reasons you mention, or at least some namespacing heuristic to closely associate the Factory class with that of the objects it creates. The key points are to encapsulate (once and only once) what it takes to create a valid instance (without unduly opening access to private implementation details of the instantiated class), and to make it easy for programmers to find out how to create an instance of the class in question. However in my experience it has been rare that the complexity of creating an instance is sufficient that a separate Factory class is warranted; I think that is an overused pattern, and Complete Creation Method suffices for me most of the time, especially for domain object classes.
With respect to the Single Responsibility Principle, I think there are other principles that are equally important, such as the Principle of High Cohesion. There is high cohesion between the implementation of a class, and the requirements for properly instantiating a class, and therefore the logic for instantiating a class belongs with the implementation of the class. Personally, I think SRP is overrated. A class should implement as many responsibilities as makes sense for it to implement, where “makes sense” means the responsibilities in question are highly cohesive.
Kind Regards,
Randy
From: moffdub [mailto:moffdub <at> yahoo.com]
Sent: Thursday, August 07, 2008
6:51 AM
To: domaindrivendesign <at> yahoogroups.com
Subject: [domaindrivendesign] Re:
Factory Method Pattern via Inner Classes
If it helps, my name is Aaron. :)
Thanks for the tip on the pattern. I have only found one good
resource on it. I will keep looking.
After sleeping on it, I agree that the inner class is a kludge, but I
think for different reasons. I reviewed what Jimmy
Nilsson had to say
about this in his DDD book regarding Factory Methods:
"Are there any drawbacks? I think the main one is that I'm probably
violating the SRP when I have my creational code in the class itself.
Evans' book is a good reminder of that where he uses a metaphor of a
car engine. The car engine itself doesn't know how it is created;
that's not its responsibility."
This is the main reason why I shy away from Factory Methods, and my
inner class con was just that -- a con. Evans also says that one of
the main points of DDD factories is to be able to swap out the
creational code for a different implementation, and I clearly can't
do that with my suggestion.
I think the best trade-off is to consult the platform's way for
friend access or package access or equivalent, and apply that to
constructors. Nilsson to wit:
"To avoid the instantiation of orders via the constructor from other
classes in the Domain Model if the Factory code is an external class
is not possible, but you can make it a little less of a problem by
making the constructor internal, and hopefully because the Factory is
there, the Domain Model developers themselves understand that that's
the way of instantiating the class and not using the constructor of
the target class directly."
But still I wonder what workaround, aside from switching languages,
would be best if the platform doesn't come to the partial rescue.
__________________
The views expressed here are mine and do not reflect the official
opinion of my employer or the organization through which the Internet
was accessed
--- In domaindrivendesign <at> yahoogroups.com,
randy.stafford <at> ... wrote:
>
> Hello Mr. Moffdub,
>
>
>
> I wish I knew your real name! You wrote:
>
>
>
> Doing Order.createOrder(-) works, but it seems contrary to the
spirit
> of separating the construction of the object from the object itself.
>
>
>
> That's the way we used to do it in Smalltalk (and I still do it
that way in Java). Kent Beck even wrote a pattern about it, called
Complete Creation Method in his Smalltalk Best Practice Patterns
book, renamed Complete Constructor in his more recent Implementation
Patterns book.
>
>
>
> I'm aware that my static inner class solution is essentially
> equivalent, save for clearer syntax for the caller.
>
>
>
> Beauty is in the eye of the beholder. I find Order.create
(customer, items) to be cleaner than Order.OrderFactory.createOrder
(customer, items). The latter seems to unnecessarily expose
implementation, and costs the development and maintenance of an
additional class which may not be entirely justified.
>
>
>
> Kind Regards,
>
> Randy Stafford
>
> http://c2.com/cgi/wiki?RandyStafford
>
>
>
> _____
>
> From: moffdub [mailto:moffdub <at> ...]
> Sent: Wednesday, August 06, 2008 4:07 PM
> To: domaindrivendesign <at> yahoogroups.com
> Subject: [domaindrivendesign] Re: Factory Method Pattern via Inner
Classes
>
>
>
> Thanks for the reply. Wouldn't delegating to a factory held in an
> instance variable cut you off from accessing private members?
>
> Assuming you are talking about a top-level class, the problem with
the
> factory using a constructor is I've made the constructor of Order
> private to force users of Order to use the factory.
>
> Doing Order.createOrder(-) works, but it seems contrary to the
spirit
> of separating the construction of the object from the object itself.
> I'm aware that my static inner class solution is essentially
> equivalent, save for clearer syntax for the caller.
>
> I think Order.OrderFactory.-createOrder(-), imperfect as it is,
makes it
> clear what is going on to someone cognizant of patterns.
> Order.createOrder(-) is a little less clear to me.
>
> --- In HYPERLINK "mailto:domaindrivendesign%
40yahoogroups.com"domaindrivendesign <at> ..., Michael Hunger
<ddd <at> > wrote:
> >
> > I could also imagine using an factory method on the Order itself
> > -> Order.createOrder(-)
> > which then either:
> > * does the creation itself
> > * delegates to a static factory like your example
> > * delegates to an factory instance held in an instance variable
> (possibly setable by Dependency Injection)
> >
> > It depends on the complexity of the setup which approach you
choose
> to start with.
> >
> > I don't think this pollutes the Order to much because the creation
> of itself unproblematic in the sense of SRP.
> >
> > Another question is why you need access to internal fields in the
> factory and not just setting them in the constructor
> > (or on the other hand in a public factory method of the order
itself)?
> >
> > Michael
> >
> > --
> > Michael Hunger
> > Independent Consultant
> >
> > Web: HYPERLINK "http://www.jexp.de"http://www.jexp.-de
> > Email: michael.hunger <at>
> >
> > Enthusiastic Evangelist for Better Software Development
> >
> > Don't stop where you are: HYPERLINK "http://creating.passionate-
developers.org"http://creating.-passionate--developers.-org
> > We support Software Engineering Radio (www.se-radio.-net)
> >
>
Change settings via the Web (Yahoo! ID required)
Change settings via email: Switch delivery to Daily Digest | Switch to Fully Featured
Visit Your Group | Yahoo! Groups Terms of Use | Unsubscribe
__,_._,___
RSS Feed