Holub on Patterns
If I can level any complaint against this book, it's probably that the title doesn't properly convey the goodness locked within. Holub on Patterns is short for Allen Holub on Design Patterns. Allen Holub is a long time expert on Design and Design Patterns, so he's the man you want to learn it from. Still, if I could name this book, it would be Object Oriented Design Voodoo. (Note: This is probably why I don't work for Apress or any other publisher.)
The book's subtitle is "Learning Design Patterns by Looking at Code." That probably conveys the work's focus a little better and it also gives away one of the book's best features: sensational examples. (These examples are in Java, another area where Holub is a well-known authority, but the concepts taught apply to Object Oriented Programming in any language.)
Titles aside, this book really is the best work I've read on design patterns. If you don't already know, design patterns are the recurring patterns of object-oriented software implementations. Luckily, you don't have to know anything about them to read this book. The author covers many patterns in rich detail from the beginning. Even if you do know your design patterns well, I'll wager Holub still has a trick or two to impress you with.
Holub discusses patterns in their ideal pure form, but much more importantly he shows them as they occur "in the wild," with multiple variations. He covers the downside of each pattern, weights the trade-offs of using them, and even gives a handful of cases where he felt they were impractical. He does all this right in the middle of complex real-world examples so you can see each point he's making. That's actual programming, folks. The good, the bad and the choices we programmers make are well presented, and that's rare in a programming text.
The book opens with two chapters that more or less cover why we need design patterns at all. Did you know getters/setters are bad? Did you know that subclassing is dangerous? If you said No to either question, you need this book and these two chapters in particular will get you up to speed on good OO practices. This section of the book is mostly theory, light on examples.
The next two chapters (covering over 250 pages) make up the heart of the book. Holub examines two examples in exhaustive detail. The first is his implementation of The Game of Life. You've probably implemented that on your TI calculator, but Holub sure didn't. He admits that his implementation is "Toy Code," but it's a robust example that involves eleven design patterns. The second example is production code, a mini database complete with SQL interpreter. This code is also swimming in pattern usage, and Holub gives you the guided tour.
I've already said these examples are great, but that claim begs some elaboration. First, we're talking about hundreds of lines of code in many of these listings. These aren't the usual contrived junk. What's more, one class may be participating in multiple patterns. Making any sense of these examples would be almost impossible if the author wasn't flawless in explaining the key points and always dropping hints about what you need to notice. This isn't light reading. It's work, but the rewards are there and it'll pay off if you really spend the effort to understand how the code works.
Finally, the book closes with an appendix that gives more typical recipe-card style listings of all the design patterns discussed throughout the text. This is a nice reference after you've finished the tricky stuff. If you're new to design patterns, you might start here, before the book throws you into the lion's den with its massive examples.
Just in case I haven't sold you on this title yet, I better mention the gorgeous hard back binding. Brilliant and sexy. How can you beat that?
Holub on Patterns is a very approachable way to learn a lot about design patterns. If you already know how much patterns can improve your object-oriented programming, you'll really enjoy Holub's presentation of the topic. If you don't yet grasp Design Patterns or haven't enjoyed other works on the subject, you'll just have to trust me: You want this book.
You can purchase Holub on Patterns: Learning Design Patterns by Looking at Code from bn.com. Slashdot welcomes readers' book reviews -- to see your own review here, read the book review guidelines, then visit the submission page.
The official site is located here.
Holub explains, check the articles on Javaworld (you can find links at Holub.com)
It took some time before Holub convinced me with his articles on Javaworld. But when I was convinced, I looked forward to the release of his book, which I have bought immediately.
BTW. Accessor/Mutator methods aren't bad always though, for example, when you use them to access a non-object-oriented part of your software system (e.g. file system / database / GUI widgets)..
Here's a good explanation: http://www.javaworld.com/javaworld/jw-09-2003/jw-0 905-toolbox.html
"Look Lois, the two symbols of the Republican Party: an elephant, and a fat white guy who is threatened by change."
Two things spring to mind (without having read the book)
1. I see a lot of code where *every* attribute is assigned a get/set method as a matter of course (someone probably hit the "select all" button when generating them in the IDE of choice). Without additional "defensive code" inside this is tantamount to simply making everything public (shiver). Only expose what you have to.
2. An object composed purely of getter/setters really is nothing more than a data container. Good OO practice suggests that objects represent units of encapsulation where *functionality* is built around cohesive sets of data. In other words its always wise to revisit how you have partitioned your design if your object model is rampant with such abstractions.. a pure data object really doesnt *do* anything.
Design pattern fans should check out Pattern Hatching: Design Patterns Applied by John Vlissides, one of the Gang of Four. Short, but interesting reading.
EricHow to detect Internet Explorer
Before perusing this discussion, you may want to get some perspective by reading Unskilled and Unaware of It: How Difficulties in Recognizing One's Own Incompetence Lead to Inflated Self-Assessments by Justin Kruger and David Dunning (Journal of Personality and Social Psychology,
Well, I didn't know much about this guy. But anybody who defends his position by referring to this psychology paper doesn't score too high in my book. If you're not familiar with the paper, it basically asserts that stupid people don't realize how stupid they are. So referring to this paper is a subtle way of saying "you're stupid, and you don't know it".
But I'll give him the benefit of the doubt.. after all some other pompous experts have referred to that paper yet raise important points based on sound theory. I.e., there is not necessarily a correlation between being an assmunch and being *wrong*.
So now I read his papers on getters/setters and he claims this is "bad" because it assumes an implementation of the underlying value:
Excuse me but having to declare orderTotal to be any particular type is a *JAVA* thing, and not universal to OO programming. In Ruby for instance:
No types or assumptions here. Since Ruby is fully OO, this will work even if amount.value returns a Fixnum, a Float, or a SomethingElseEntirely.
He says a "better" way is:
But this is just syntax. In Ruby I would just write:
And it doesn't matter what the types (classes) are.
Poor guy is stuck in a statically typed Java hell, with distinctions between primitive types and objects, of course he's gonna think getters/setters are evil and he's gonna become obsessed with keeping his data hidden in a box or behind opaque methods! I can just imagine his code filled with thousands of builder objects with 2-3 levels of abstraction .. and it will just be a grotesque simulation of a true dynamic language in the end, with everything completely decoupled.
I don't know if I should bother reading any more of his writings since I don't use Java.... is the rest of his work "how to get around Java's shortcomings" or is there something a general purpose OO practitioner might find useful???
Let's take an example in java:
class Foo {
public int getValue() { return m_value; }
public void setValue(int v) { m_value = v; }
private int m_value = 0;
}
and now this:
class Foo {
public int m_value = 0;
}
There is absolutely no difference in functionality here, so there is no need for getter/setter for something which does not get any benefit of scope.
If you has something like this, then it makes sense to have a getter/setter:
class Foo {
public int getValue() { return 2 * m_value + 10; }
public void setValue(int v) { m_value = v -5; }
private int m_value = 0;
}
Here the implementation hides away the logic which the user should not care about (this is a simplistic example, but you get the idea).
People should use patterns to make coding easier, not code so that you can use patterns.
Philip Crow wrote a very original piece on how to avoid OOP and still use patterns with Perl's special built-in features
http://www.perl.com/pub/a/2003/08/15/design3.htm l
They've been available with Delphi(not coincidently the same designer for Delphi and C#) for hmm... about 6 years now? more?
.NET IL is smart enough to redirect a get {return } simply to the member variable. Like a read property accessor directive with Delphi.
What I'm wondering is if
Object Oriented languates/programming wasn't invented for DoD. You're thinking of Ada, which, in it's original incarnation was an Object-based system but didn't support proper inheritance or polymorphism (Ada'82).
OO started with Simula and Smalltalk, with Simula67 being the object oriented base of C++.
And if you don't know what you're doing in a particular paradigm you usually end up with dreck nobody wants to maintain.
Slashdot's name? When my compiler sees
Check a principle called the 'Law Of Demeter'. I have a paper about it on my website called, "the Paperboy, the Wallet, and the law of Demeter". This will answer your question. In short, it is better to provide the common functions developers will need of your objects, rather than just expose the parts and let them manipulate them manually. Any piece of advice can be followed pragmatically or dogmatically though... Your mileage may vary.
This is a bad approach. The Item object here is a representation of data. Any logic imposed on that data should not be encapsulated within the Item object itself. The addToCart() method is an implementation detail, describing one possible use of the item's data within this particular system. It is more appropriate to implement the addItem() method on the cart.
Consider this, the addToCart() method is implemented in the Item object. Elsewhere in the system, we want to implement an Invoice object. The Invoice object contains, among other things, an aggregate (collection) of Items. If we want to add an Item to the invoice, using the method described in your post, we would have to add an addToInvoice() method to the Item object.
Simple OO design tells us that the Item object has no business knowing the implementation of an Invoice (or a Cart or a Sales Report or a Catalog, etc). A data item should never be aware of (or care) how it's being used within a system. The maintenance effort alone would be a nightmare and cause the system to crumble. Consider: you change the process of how a cart adds items - what effect will this have on the invoice?
At a simple level, objects should be thought of in terms of nouns and verbs - what something "is" and what something "does". Keep these two concepts separate and you will be on the right track to good design.
Ryosen
One man's "Troll, +1" is another man's "Insightful, +1".