Practices vs. Simplicity

05/02/09

Permalink 12:08:57 pm, by truewill Email , 385 words, 149 views   English (US)
Categories: Agile, IoC, Books

Practices vs. Simplicity

I’ve been (slowly) reading Scott Bain’s book Emergent Design. I’m roughly halfway through it, and I agree with most of his views and recommendations.

I cannot agree with the practice of encapsulating the constructor, though.

Bain recommends making constructors private and adding static factory methods to classes when they will be used by client classes. This avoids the new keyword outside of the class, with the goal of reducing coupling and making the system more open-closed.

I completely agree with the goals of this practice, and generally agree with Bain’s underlying principle (separating use from construction). I disagree with making this a standard practice.

To be fair, Bain states that this is an “at least do this” practice, and that separate factories and other techniques may be used instead where appropriate. I still believe it is not appropriate for general use.

Being a fan of XP, I favor doing the simplest thing that could possibly work. Bain suggests that factory methods support adding subclasses at a later time. I would not add the factory until that time comes. This practice provides benefit only if the class with the encapsulated constructor becomes polymorphic. If we favor composition over inheritance, that’s not as common as it once was.

He talks about issues extrinsic to the client for determining which subclass to instantiate. He actually implies (p. 160) that coupling the factory method to a GUI might be acceptable! Don’t do it. The moment you do, your class with the encapsulated constructor becomes effectively untestable.

What’s more, I believe that extrinsic issues like configuration settings will tempt developers to use Singletons (read: global state) as “determiners.” Again, this makes for classes that are difficult to test.

So what would I recommend instead? Dependency Injection works well for me. This can be done simply through manual constructor injection. If the system is sufficiently complex, I introduce an IoC (Inversion of Control) container. This decouples my classes, makes them easy to test, and provides great flexibility.

An IoC container is not needed on every project. Neither are factory methods.

Update - May 3, 2009

I sent Mr. Bain a link to the post, and he was kind enough to respond in the comments. Please read his well-stated position. Again, we both have the same goals.

Update - June 21, 2009

See also: Mini-review: Emergent Design

Comments, Pingbacks:

Comment from: Scott Bain [Visitor] Email · http://www.netobjectives.com
Thanks for your interest in the book, Bill, and for the thoughtful critique.

I guess the main issue here is the one we agree on... to reduce concrete coupling in systems by separating the use of an object from its creation. My main goal was to encourage teams to adopt some minimal practice to make this happen generally across the architecture, without over-designing. Seems we agree there too.

I also agree with the notion of simplicity; I just don't think that adding a one-line static method to service classes and changing "new Thing()" to "Thing.getInstance()" in client classes is non-simple. Ironically, I find the universal application of dependency injection (your preference) to be the more complex approach. Reasonable people can disgree on these details, and you certainly know your own team and your own projects better than anyone, so I'll assume the forces you routinely deal with are somewhat different from mine, and this consequently leads us in slightly different directions.

Interestingly, the use of static getInstance() methods can actually enable the addition of dependency injection at a later time, because we control what methods produce, while we do not control what constructors produce. getInstance() is not, however, a Factory Method. Factory Method is a pattern, wherein a virtual method is called in a base class to produce a dependency, with the intention that derived classes will override it to produce whatever is appropriate. The introduction of mocks for testing is a great application of this pattern, and the getInstance() I use can delegate to just such a method, if DI is determined to be desireable at any future point.

That said, I think it's more important to select a practice that will succeed across the team. Your mileage may vary.

On the coupling of factories to the GUI, you're right. I think I got a little sloppy in my language... by "the GUI" I should have said "the GUI layer". I use a version of the Mediator Pattern to shield mid-tier logic from the actual GUI, for the very reason you say, to maintain testability (Mediators are easily mocked).

The last thing I comment on is your notion that "we favor composition over inheritance"; I certainly agree, and this is a cornerstone of Pattern (GoF) thinking. However, you'll notice that in the patterns what is delegated *to* in a compositional relationship is often polymorphic, often through the use of inheritance. I think the real question is "what do we use inheritance for", not whether to use it or not. I've gone on long enough here, so I'll just refer to a recorded presentation I did on this:

http://www.netobjectives.com/resources/articles/when-how-use-inheritance

-Scott Bain-

PermalinkPermalink 05/02/09 @ 15:10

Leave a comment:

Your email address will not be displayed on this site.
Your URL will be displayed.

Allowed XHTML tags: <p, ul, ol, li, dl, dt, dd, address, blockquote, ins, del, span, bdo, br, em, strong, dfn, code, samp, kdb, var, cite, abbr, acronym, q, sub, sup, tt, i, b, big, small>
(Line breaks become <br />)
(Set cookies for name, email and url)
(Allow users to contact you through a message form (your email will NOT be displayed.))
The name truewill is composed of two other words. What is the SECOND word?

Development Central

Development Central is the blog of Bill Sorensen, a professional software developer. Much of this will relate to C#, .NET, and OOP in general.

Disclaimer
These postings are provided "AS IS" with no warranties and confer no rights.

Search

Categories

Linkblog

b2evolution

contributors

XML Feeds

What is RSS?

Who's Online?

  • Guest Users: 2

powered by b2evolution free blog software