Slashdot Mirror


Holub on Patterns

James Edward Gray II writes "Apress sent me a copy of Holub on Patterns for review, and for that I'm extremely grateful, because this is a gem of a book I would not have liked to miss. Odds are, most object-oriented programmers will feel the same, so allow me to share the highlights." Read on for the rest of Gray's review. Holub on Patterns: Learning Design Patterns by Looking at Code author Allen Holub pages 414 publisher Apress rating 9 reviewer James Edward Gray II ISBN 159059388X summary Design Patterns taught through Real World Programs.

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.

211 comments

  1. Witch doctors by MikeMacK · · Score: 3, Funny
    Still, if I could name this book, it would be Object Oriented Design Voodoo.

    Great, now we're getting book reviews by witch doctors!

  2. Official site by the_mighty_$ · · Score: 5, Informative

    The official site is located here.

    --
    VI VI VI - the editor of the beast!
    1. Re:Official site by jsitke · · Score: 1

      I am looking forward to this book. There are not enough good (and new) books on patterns.

  3. Getters/setters bad? by d_jedi · · Score: 5, Interesting

    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.

    Can someone explain why accessor and mutator methods (I assume this is what he means by "getters/setters") are bad?

    --
    I am the maverick of Slashdot
    1. Re:Getters/setters bad? by swimmar132 · · Score: 0, Redundant

      I'd like to know too.

    2. Re:Getters/setters bad? by Anonymous Coward · · Score: 2, Insightful

      Under the hood, actuators and mutators are method calls (at least in C#), but if the property is simple enough, there's no reason it can't be treated like simple field access.

      Properties allow you to wrap your fields with business logic and validation, so I don't see what's so bad about that.

    3. Re:Getters/setters bad? by Misch · · Score: 4, Insightful

      Can someone explain why accessor and mutator methods (I assume this is what he means by "getters/setters") are bad?

      My guess is that in some instances, publically accessible getter/setter methods can be construed to be "exposing the underlying implementation" of a class. Of course, that just means you need to judiciously use getter and setter methods.

      That's my guess at least. I suppose I should read the book.

      --

      --You will rephrase your request for me to go to hell. Goto statements are not acceptable programming constructs
    4. Re:Getters/setters bad? by SpaceTux · · Score: 4, Informative

      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)..

    5. Re:Getters/setters bad? by samberdoo · · Score: 1

      I also want to know why inheritance, which I believe he implies by "sub-classing", is bad. Seems like they are now throwing out the building blocks of OO.

    6. Re:Getters/setters bad? by homebrewmike · · Score: 4, Informative

      Here's a good explanation: http://www.javaworld.com/javaworld/jw-09-2003/jw-0 905-toolbox.html

    7. Re:Getters/setters bad? by FerretFrottage · · Score: 4, Informative
      --
      "Look Lois, the two symbols of the Republican Party: an elephant, and a fat white guy who is threatened by change."
    8. Re:Getters/setters bad? by Anonymous Coward · · Score: 0

      Good question. I do know since using Ruby that having a distinction between fields and methods is a bad thing, because it slows down refactoring and increases the cost of maintenance, and also allow for a uniform syntax for assigning variables and calling mutators.

      e.g.:

      x = 3 # variable
      obj.foo = 4 # method call

    9. Re:Getters/setters bad? by fizban · · Score: 2, Insightful

      In the OO world, objects come in two basic flavors: data objects and interface objects.

      Data objects are just groupings of data. The member variables should be public and accessible to it's users.

      Interface objects, however, encapsulate their data. They don't require the user to know about their internal data members and only provide methods members that the outside world can use to perform actions with that object.

      In the first case, you don't need getters and setters because the members are already public.

      In the second case, you shouldn't provide getters and setters because you're breaking the encapsulation.

      If you have classes with lots of getters/setters, then those classes are really just data objects and you should just make the members public and save yourself a bunch of typing.

      --

      +1 Insightful, -1 Troll. What can I say, I'm an Insightful Troll.

    10. Re:Getters/setters bad? by Greyfox · · Score: 3, Insightful
      Object Oriented programming is all about hiding data. You expose just the data you need through very specific interfaces. If you have an object that has getters and setters for every data element in the object then you're still exposing the internal workings of that object and should reconsider your design.

      Of course, being a programmer also means knowing when to break the rules, and there will be some times when you can't avoid using them. IIRC, a lot of Java stuff requires them. I prefer not to use Java if I can avoid it.

      --

      I'm trying to teach myself to set people on fire with my mind... Is it hot in here?

    11. Re:Getters/setters bad? by fartrader · · Score: 3, Informative

      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.

    12. Re:Getters/setters bad? by UWC · · Score: 2, Interesting

      I was recently reading up on .net stuff and came across a description of properties. My previous exposure to design patterns was pretty much exclusively C++ based. I agree that addressing simple actuator and mutator functionality would do well to be treated at a lower level than method calls, but I had never come across the concept of properties like that. The examples in what I was reading used C# but apparently properties are also usable in the other .net languages. Is such an implementation fairly new, or at least not introduced widely to C++ until .net?

    13. Re:Getters/setters bad? by Dormann · · Score: 3, Insightful
      Read it again. He says that sub-classing is dangerous, not bad.

      In the same sense that using a chainsaw is dangerous, but not necessarily bad.

    14. Re:Getters/setters bad? by swimmar132 · · Score: 1

      Composition should be favored to inheritance. Reason: If you change the base class, you probably gotta change all the other classes that inherit from that.

    15. Re:Getters/setters bad? by Anonymous Coward · · Score: 0

      something everyone should be aware of anyways..
      inheritance is a powerful tool. any powerful tool can cut both ways.

    16. Re:Getters/setters bad? by Anonymous Coward · · Score: 2, Insightful

      Nice how everyone who replied thus far failed to mention the Uniform Access Principle. Google it. That's why mutators/accessors are generally a good idea.

      Best practices may be generally preferable to other practices, but won't apply in every situation. Be pragmatic people!

      And to those of you talking about 'data classes', you're betraying a C-like heritage where data resided in structs or unions because of language limitations. Please keep your OO misconceptions to yourselves!

    17. Re:Getters/setters bad? by emiddlec · · Score: 4, Insightful
      The article Why getter and setter methods are evil (from above) includes the following:

      1. A fundamental precept of OO systems is that an object should not expose any of its implementation details. This way, you can change the implementation without changing the code that uses the object. It follows then that in OO systems you should avoid getter and setter functions since they mostly provide access to implementation details.

      Apparently the argument against getter / setter functions goes..

      1. OO systems should not expose implementation
      2. Getter and setter functions mostly expose access to implementation details
      3. Therefore, OO systems should avoid getter and setter functions

      While the logic is sound, I think that item #2 is debatable.. If you design an object and mindlessly add get/set functions for every piece of private data in the object, then you're probably guilty of exposing the implementation. But if you design the object's public interface first, and decide on the private data afterwards, I would guess that you're probably in the clear to have used get/set functions "correctly." IMO it's not the functions themselves that are the problem, but rather the adherence to correct design principles.

    18. Re:Getters/setters bad? by plover · · Score: 1
      I'm assuming they don't like it because it promotes "intimate" knowledge of the object.

      If you have a rule object whose job is to compute the scoring moves of a game, you shouldn't be asking it "what is the score of a headshot?" You should be telling it "I made a headshot" and let it worry about the score.

      If you start having other parts of the app getting that intimate knowledge, your app "crusts over". Now, if you change the scoring rules regarding headshots, not only do you have a rules engine to update but you may have to hunt down other classes that were foolish enough to get that data.

      This generic rule doesn't really apply to the case of a simple storage class. There, the whole idea of a storage class is to use getters and setters to validate the data. This maxim applies more to rules and business logic.

      --
      John
    19. Re:Getters/setters bad? by Anonymous Coward · · Score: 1, Insightful

      yes but then you are assfucked if you want to trigger an event when that value is changed. hence setters are good here. something like event ValueChanged

    20. Re:Getters/setters bad? by GuyWithLag · · Score: 2, Insightful

      Funny, I allways thought that GUI widgets were THE example of OO-ness....

    21. Re:Getters/setters bad? by achacha · · Score: 2, Informative

      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.

    22. Re:Getters/setters bad? by Doomdark · · Score: 1
      IIRC, a lot of Java stuff requires them. I prefer not to use Java if I can avoid it

      Actually, it's "only" many (most) Java data-binding libraries/frameworks that require them; and even then, Objects in question are mere data containers (data transfer/access objects etc). So avoiding the whole language is bit silly, if the main reason is avoiding having to create get/set methods. Java as a programming language has no dependency on such methods.

      However, I also strongly dislike the "automatic" (ie. add get/set methods for all instance variables, without any consideration) use of get/set methods many (esp. junior) java programmers do; and blame either idiots who misunderstood the whole bean idea. Beans were nothing but a simple hack to allow tools to work around the problem of Java missing first-class properties as language constructs (C# has them, thanks to Java and beans exposing the lack in all of its gory). Now there are programmers who think that there's something more to beans than simple work-around using naming convention and reflection... and that's scary, because they really have to unlearn all that nonsense; which takes more time than learning useful things the first time.

      --
      I like paying taxes. With them I buy civilization -- Oliver Wendell Holmes
    23. Re:Getters/setters bad? by chromatic · · Score: 3, Insightful

      Polymorphism a the building block of OO, not inheritance. It's a shame that so few popular languages make this clear.

    24. Re:Getters/setters bad? by chromatic · · Score: 1

      I meant is a, not a the. (I don't normally write Franglais.)

    25. Re:Getters/setters bad? by Anonymous Coward · · Score: 1, Informative

      They've been available with Delphi(not coincidently the same designer for Delphi and C#) for hmm... about 6 years now? more?

      What I'm wondering is if .NET IL is smart enough to redirect a get {return } simply to the member variable. Like a read property accessor directive with Delphi.

    26. Re:Getters/setters bad? by Derkec · · Score: 1

      By the same token, programming to interfaces is often preferable to subclassing.

    27. Re:Getters/setters bad? by philci52 · · Score: 5, Insightful

      In the first case, you don't need getters and setters because the members are already public.

      Having public members is generally a bad idea and gives me nightmares of old C structures. Here is the reason that you should use set/get methods:

      1. Debugging - Try and trace a variable every time it is set when the variables are public. Wonder why you can't figure where it is going wrong? Adding 100 break points? Using set/get here can save hours of debugging.

      2. No loss of Speed - most compilers will optomize your set/get functions if they are inline, so there is no performance penalty (atleast for c++).

      3. Maintainance - Suppose that when data member A is updated, now a count needs to be kept. Using a setter function allows you to change code in one 1 place. Also, suppose a variable type changes from an int to a double. You can still keep around the integer setters/getters for older classes and use new accessor for the new methods for objects that need it.

      From the article, its not that setters/getters are bad themselves, but that overuse of them is bad. Here is the key quote: Don't ask for the information you need to do the work; ask the object that has the information to do the work for you.

    28. Re:Getters/setters bad? by RetroGeek · · Score: 1

      Sure, but if you allow direct access, then later decide that you DO need to condition the value before it is available publicly, then you are hooped.

      By using get/set all the time, you can add the new functionality with affecting other code.

      --

      - - - - - - - - - - -
      I am a programmer. I am paid to produce syntax not grammar. Deal with it.
    29. Re:Getters/setters bad? by fupeg · · Score: 2, Insightful

      Your "data object" is not an object at all. Read the most basic definition. Your "data object" is exactly what Holub is talking about as being "evil." Your "data object" is a struct, and you are being procedural, not object oriented. The whole point of OO is to combine these two things into an object. Accessors violate this paradigm. In a good OO system, other objects never ask for information about other objects, they simply ask the other object to perform tasks.

    30. Re:Getters/setters bad? by oo_waratah · · Score: 1

      I think the classic explanation is more of you perform actions on objects not assign values. Therefore you would not be assigning a '5' to a value you would be performing an action like 'fill tank' on a car object with 5 (meaning litres).

      Calling the routine literally get and set shows no 'object orientation'. Therefore you consider them bad because of stylistic ideals which is to think in actions rather than programatically.

      Like all rules (like speeding when driving) it takes experience to know when to break the rules and by how much :-)

    31. Re:Getters/setters bad? by Anonymous Coward · · Score: 0

      Assume you have a class Money { double getValue(); }

      What happens when you introduce Euro?

    32. Re:Getters/setters bad? by Cyberfox · · Score: 3, Interesting

      Greetings,
      Data objects are just groupings of data. The member variables should be public and accessible to it's users.

      This is the only thing I disagree with in that. I believe that a get/set interface to data objects is in fact the only right place for get/setters.

      Why? Because you might want to abstract that data object into something more intelligent in a later refactoring, and then you have the burden of replacing every variable reference in everything that touches that class. Nasty, nasty stuff, and it's better to design that nastiness out in the first place.

      I believe in no public member variables, as a general rule (breakable, of course, on occasion, but terribly rarely), as it causes too tight a binding between classes and the value objects that are passed around (called 'tying' by some). This may put me at odds with Holub (I haven't read this book yet), but it wouldn't be the first time.

      Holub is an EXCEPTIONALLY good introductory author, very easy to read, and clearly brings you to the point he's trying to make. However, I recall coming back to his C books after many years as a professional developer, re-reading them out of curiousity, and realizing that he was teaching a few principles that were questionable at best, and ignored at-the-time best practices. Now it's very possible that he would also think they are questionable these days, but putting them in a book lends them an air of authority through time.

      I'll probably pick up the book, as more examples of good pattern use are always valuable, but as an engineer who has developed countless classes where 'value objects' become more intelligent, I strongly recommend against direct member variable access.

      -- Morgan Schweers, CyberFOX!

    33. Re:Getters/setters bad? by fupeg · · Score: 1, Informative
      By using get/set all the time, you can add the new functionality with affecting other code.
      Actually by having accessors and then using them in other parts of your code you will have to refactor tons of code anytime the data behind the accessors changes. If you have other objects that need to manipulate data from another object ("data object"), then your these manipulations should be done by the "data object." If that's not possible (like your the manipulation needs data from multiple objects) then your design is flawed and you need to encapsulate the data better.
    34. Re:Getters/setters bad? by alw53 · · Score: 2, Funny

      >A fundamental precept of OO systems is that an >object should not expose any of its implementation >details.

      That's why we don't call hash tables HashTables, we call them "unorderedBagsIndexedByArbitraryKeysWithConstantTi me Acces", because that describes the PROPERTIES of the class rather than the IMPLEMENTATION. Oh, wait...

    35. Re:Getters/setters bad? by marms · · Score: 3, Insightful

      An obvious reason not to use "public" members in Data Objects is if the member must be validated to prevent illegal values from being assigned. Or if changing one member will automatically cause other members to be changed. Or if the internal encoding of an object differs from the external representation. Or if sychronization or transactions are needed. Or to prevent access/mod by certain classes or users or under other circumstances. Need I go on? Yes, there are times when using "public" members is fine (think: simple code). But there are a multitude of reasons not to. YMMV.

    36. Re:Getters/setters bad? by Cyberfox · · Score: 1

      Greetings,
      A telling quote from Holub's article on his site about getters/setters...

      We do know how we will use the classes, so you don't have to waste time building unnecessary flexibility.

      His article actually explicitly is against the public accessible groupings of data, preferring instead what is (to me) equally distasteful, which is having the 'data objects' know everything that could be done with them, and contain the functionality to do it all. This is fine if you never need flexibility in your data, for different representations, display formats, UI toolkits, calculations, business logic, etc., and you can predict the complete set of uses in advance, like in examples in a book. Most real software development doesn't work like this though.

      Certainly there are occasions when this is right, but most of the time this is a recipe for disaster, as you put too much system knowledge, and therefore too much tying between classes, in what should just be a relatively simple representational class.

      It depends a lot on what you're doing, of course, and I'd definitely agree that keeping get/set to a minimum is important (and even moreso for set than get), but it's definitely not a tool to discard from your toolset because Holub says so.

      -- Morgan Schweers, CyberFOX!

    37. Re:Getters/setters bad? by TheSunborn · · Score: 3, Insightful

      (Talking about the way java does things)

      But you don't code to the interface(api) of a HashTable. You code to the Map interface, which is described as: "
      An object that maps keys to values. A map cannot contain duplicate keys; each key can map to at most one value."

      And you don't(Should not) give a HashTable to a method. Give it a Map insted. The only place in your code where the exact type matters, is where you create the object.

      That most people call them hashtables insted of associative array(or maps) are because they mix implementation and interface.

      I once did implement a Map using a linked list. Not effective, but a nice way to show the difference between interface and implementation.

    38. Re:Getters/setters bad? by killjoe · · Score: 3, Insightful

      It looks like we have come full circle. Nowadays it's fashionable to create value objects which are pretty much like the hashes and recordsets of the old days. Make value objects with public attributes, make action objects that take the value objects and maipulate them.

      As I said just like the old days.

      --
      evil is as evil does
    39. Re:Getters/setters bad? by ashultz · · Score: 1


      Well, there is no difference in functionality in this version, but when I later want to change it so that m_value is actually MValueService.getWidgetCount() in the simpler version I can't unless I control every single class that uses this class and accesses the variable I now want to hide.

      Plan for the future, and don't expose instance variables except in private inner classes and other very limited use containers.

    40. Re:Getters/setters bad? by KyleCordes · · Score: 2, Insightful

      I usually say something like this:

      Map someMapINeed = new HashMap();

      so that the implementation chosen (HashMap, the Java 1.2+ expression of the general idea of a hash table) is present only at that one spot, the rest of the code doesn't care about the Hashness of it, it just uses it as a Map.

      It is a common "smell" in Java code, to refer to something specific (HashMap) in a parameter list (most commonly) when you only need the generic.

    41. Re:Getters/setters bad? by kpat154 · · Score: 2, Insightful

      Ok, this post completely misses the point. You don't provide getters/setters to insulate the client from functionality - you provide getters/setters to insulate the client from change.

      Change is inevitable. You've got to plan for it. So, 6 months down the road when you realize that you need to change this requirement and add some functionality you won't be able to because you've directly exposed the member without hiding it behind a getter/setter.

    42. Re:Getters/setters bad? by daviskw · · Score: 1

      Item 41 in the book "C++ Coding Standards" is:
      Make data members private, except in behaviorless aggregates (C-style structs).

      We've gone round and round on this where I work but the long and the short it is that Sutter and Alexandrescu are correct. Large collections of setters/getters are generally signs of a bad design. If you have a struct that maybe has some basic functionality that isn't germain to the purpose of the class then simplify it and put it in structs. If it does something then design it so that you don't have ten or twenty setters and getters for your class.

      --
      Beware the wood elf!!!
    43. Re:Getters/setters bad? by owlstead · · Score: 1

      IIRC, a lot of Java stuff requires them.

      Hmmm, I must be new to Java programming then. Some languages may use properties instead, but whats the difference? Anyway, people tend to forget that Java is a language that has little rules, and is thus easy to learn and parse (use Eclipse, and you know what I'm talking about). Adding properties etc. etc. would break that design decission. Just don't use get/set sparingly (think about your interface) and you're fine. Most java IDE's out there can create getters and setters automatically in the case that you do want to use them AND the type of the getter/setter is equal in the interface and the implementation.

    44. Re:Getters/setters bad? by billoo · · Score: 1

      One word: Refactor
      If you ever need to Refactor the latter Foo class so that the value is calculated/concatenated/comesOutOfTheAssinated then you are Foobar, but in the former Foo class you are covered. That was the whole evolution over C struct thingy was.

    45. Re:Getters/setters bad? by Elwood+P+Dowd · · Score: 1

      I don't think that's what he's talking about.

      He's saying that if you need to access data in an object, you have probably failed to properly design your objects. He's saying that you should minimize any data access and any data sharing between objects. If some object has information that you need in order to do something, tell the object to do it for you.

      Thus, if you feel the need for getters and setters, you've made a mistake elsewhere.

      Whether or not that's always good advice I'll leave to someone who is a better programmer than me. I'm best at VBA coding in MS Access. So maybe I should just sit down.

      --

      There are no trails. There are no trees out here.
    46. Re:Getters/setters bad? by chris_eineke · · Score: 0
      1. Debugging - Try and trace a variable every time it is set when the variables are public.

      I vividly remember using the "Set breakpoint on access to memory range" in SoftICE. Modern (java) debuggers ought to handle access to variables and break execution when access does happen. Besides that, public variables are bad. Hide your implementation.

      2. No loss of Speed - most compilers will optomize your set/get functions if they are inline, so there is no performance penalty (atleast for c++).

      There wouldn't be a performance penalty at all if you properly designed your classes. Hide your implementation.

      3. Maintainance - Suppose that when data member A is updated, now a count needs to be kept. Using a setter function allows you to change code in one 1 place. Also, suppose a variable type changes from an int to a double. You can still keep around the integer setters/getters for older classes and use new accessor for the new methods for objects that need it.

      Hide your implementation. Keeping a count of accesses to a data member can be done privately (sounds kinky ;). Again, other object should not poke into other objects blueprints. That's what a well-defined public interface is for.

      --
      "All you have to do is be fragile and grateful. So stay the underdog." Chuck Palahniuk, Choke
    47. Re:Getters/setters bad? by Anonymous Coward · · Score: 0
      No no you're missing the point.

      First of all, needing different syntax for fields vs. getters/setters is an implementation detail. In Ruby for example there's no difference:
      class Foo
      attr_accessor :value
      end
      f = Foo.new
      f.value = 4
      puts f.value

      vs.
      class Foo
      def value=(v) @value = v - 5 end
      def value() 2 * @value + 10 end
      end

      # client code unchanged
      f = Foo.new
      f.value = 4
      puts f.value
      What the author is saying is that you shouldn't concern yourself with that value AT ALL, and anything you need to do with the value should be exposed as a method.

      This is *sometimes* true. It depends on what kind of model you're creating. If you are creating a Measurement object to represent a number with units, you probably don't want to have a setValue() and setUnits(), because those things would never change separately. I.e., 3 kilos would never become 3 meters.

      The author would argue that you shouldn't have getValue or getUnits either, but I would argue you DO because you might want to *display* the damn thing somewhere.

      But it has nothing to do with fields vs. methods.
    48. Re:Getters/setters bad? by Greyfox · · Score: 2, Insightful
      Check out the specs for anything with "bean" in the name, and also java data objects. Pretty much anywhere you get into pushing data around, the spec will call for getters and setters.

      Having the IDE create them automatically is going the wrong way, encouraging bad programming habits and illustrating the IDE designer's failure to comprehend the nature of object oriented design.

      --

      I'm trying to teach myself to set people on fire with my mind... Is it hot in here?

    49. Re:Getters/setters bad? by KillerCow · · Score: 1

      From the article, its not that setters/getters are bad themselves, but that overuse of them is bad. Here is the key quote:
      Don't ask for the information you need to do the work; ask the object that has the information to do the work for you.


      I don't mean to harp on this, but this point is about both Abstraction and Encapsulation. Which may help put it into perspective as to why you should do it this way.

    50. Re:Getters/setters bad? by jquiroga · · Score: 1

      Well, Holub explains this at length in his article. Let me rephrase and summarize what I understand of what he says.

      I think his chain of reasoning (and mine :) is somewhat like this (anyone can personally agree or disagree with any of these, of course):

      - Software design is a separate activity, different from coding.
      - Good software designs must stick to their underlying paradigm (OO in this case) as much as possible, to reap as much of its benefits as possible.
      - Encapsulation is a quality that provides most of the benefits of OO.
      - Encapsulation is a quality that good OO designs must pursue with a passion, or else they are very bad OO designs, measured in OO benefits reaped.
      - Encapsulation means knowing as little as possible about the inner implementation of an object, ideally nothing.
      - Knowing nothing about the inner implementation of an object, and still be able to work with it, is almost always possible.
      - Getter and setter methods reveal part of the inner implementation of an object, so using them means running away from encapsulation and embracing the opposite.
      - Getter and setter methods are very bad for the quality of the design that includes them.

      I don't think Holub believes getter and setter are *always* bad. I do think he believes getter and setter methods are overused. I also think he believes the availability of getter and setter methods discourages long and hard thinking about the best possible design in a given circumstance, so he naturally prefers to approach OO design as if getters and setters would not exist.

      My personal opinion (and experience) is that he is spectacularly right.

      These phrases from his article include the above, in his words:

      A fundamental precept of OO systems is that an object should not expose any of its implementation details. This way, you can change the implementation without changing the code that uses the object. It follows then that in OO systems you should avoid getter and setter functions since they mostly provide access to implementation details.

      One basic principle of OO systems is data abstraction. You should completely hide the way in which an object implements a message handler from the rest of the program. That's one reason why all of your instance variables (a class's nonconstant fields) should be private.

      This implementation hiding principle leads to a good acid test of an OO system's quality: Can you make massive changes to a class definition--even throw out the whole thing and replace it with a completely different implementation--without impacting any of the code that uses that class's objects? This sort of modularization is the central premise of object orientation and makes maintenance much easier. Without implementation hiding, there's little point in using other OO features.

      Since accessors violate the encapsulation principle, you can reasonably argue that a system that heavily or inappropriately uses accessors simply isn't object oriented. If you go through a design process, as opposed to just coding, you'll find hardly any accessors in your program. The process is important.

    51. Re:Getters/setters bad? by Anonymous Coward · · Score: 0

      My God! His solution is to have importer/exporter interfaces from/to strings!?! There goes type safety down the drain. And this is just to avoid implementing proper abstractions. Of course it's not easy to deal with various currency formats, but that's no excuse for using strings for all your data.

    52. Re:Getters/setters bad? by aCapitalist · · Score: 0

      Too many setters might be a bad thing, but getters is not necessarily a bad thing. See the post above you and my response for a further explanation. If you're exposing a bunch of int getters than you might have a problem, but to say that you shouldn't expose other objects within an object is too limiting because then you end up with fat interfaces.

    53. Re:Getters/setters bad? by Canberra+Bob · · Score: 2, Insightful

      "In a good OO system, other objects never ask for information about other objects, they simply ask the other object to perform tasks"

      At some stage you will have to get some data from an object. Very simple example, lets say you are writing up a shopping cart. Add item objects to the cart. How will this cart keep track of the subtotal without querying the item objects as to their price?
      OK, we have:
      cart.add(item);
      At some stage the cart object will have to call: item.getPrice();
      Very simple example, but I am curious how this shopping cart would operate if the item was never queried to find out its price?

    54. Re:Getters/setters bad? by orthogonal · · Score: 1

      Can someone explain why accessor and mutator methods (I assume this is what he means by "getters/setters") are bad?

      It's a bad design that promotes bad usage.

      Consider the extreme case, where all attributes (sub-objects) of the main object are accessable and mutable: in this case, there's little real difference between the object in question and a C struct.

      You've gained nothing over a C struct other than the ability to call it an object.

      Except to essentially log any calls to getter/setters -- but you can't actually use code to set contrainsts or policy or to maintain object consistency, as to do so would be to confuse the programmer using the object. If object Square has a setWidth and a setHeight, either the using programmer can set the height and width to different values -- thus making a non-square Square -- or you have code in each setter that makes the both height and width the same, preserving the squareness but fundamentally confusing the programmer who takes the setter names at face value.

      Since one point of object orientated design is to create working abstractions that know how to do thier own job, accessors and mutators undermine this, suggesting that the programmer using the object is able to, and perhaps even required to set and get the minutiae that controls that object's operation.

      The object's internals, how it does its job, should belong to the object so long as the object fulfills its contract, and as much as possible, this should be done via comand-like method calls (doThis(), doThat(), checkIfDone()) and not by the setting of (or checking of) values internal to the object. The using programmer gains little if he has to micro-mange an object. The using programmer gains much if he can just use the object without having to know how its internals work.

      Real object oriented design involves designing objects that do what they are supposed to do and which are expected to manage their own internal state and keep it internally consistent.

      Take for example the C++ std::string; it manages its own memory, and makes sure any allocated memory is ultimately deallocated, so that the using programmer doesn't have to -- letting the using programer have have a setter to directly manange that memory would undermine the major reason for having a string class in the first place. For extraordinary situations (mostly interfacing with pre-Standard or C libraries) there are ways to directly access that memory, but rather than use a getter, a puposely more obscure and ugly syntax is required, precisly in order to underscore the dangerousness of so doing.

      Another reason to prefer not to use setters and getters is to use objects as immutable or "value" objects -- Java takes this to a (in my opinion bad) extreme in order to avoid the number one Java pitfall, pointer aliasing; C++ avoids the pointer aliasing but likes "value objects" because they behave more "like" automatic (local/stack) variables, even if their implementation is on the free store, and because they make it easier to use C++'s "resource initialization is acquisition" (RIIA) idiom.

      In using value objects most (and for immutable objects, necessarily all*) attributes are set when the object is constructed, via ctor arguments, and rather than enage in messy fiddling, if new values are needed, a new object is constructed.

      *Unless of course the immutable object has a uses-a relationship to a mutable object, which can be a source of much merry foolishness in Java, again of the pointer aliasing variety.

    55. Re:Getters/setters bad? by adamy · · Score: 1

      Refactor when you get there. You will probably never get there.

      --
      Open Source Identity Management: FreeIPA.org
    56. Re:Getters/setters bad? by Forbman · · Score: 1

      If other objects should never ask for information about other objects (whether it be from the other objects or some other property fairy), then why does OO so depend on RTTI (a particular kind of object property fairy) and other methods of type discovery to work?

      Hmm...

    57. Re:Getters/setters bad? by KillerLoop · · Score: 1

      I don't quite see where hashes and recordsets help the compiler to catch your typos. As with both hashes and recordsets, you rely (for the most part) on some String key, which is a bit of a nuisance when a typo etc. happens. Oh yes, you can put the keys in a Constants class or somesuch, but this becomes a pain rather fast.

      Not that I'd see this as the most gigantic leap ever done in programming, but it adds to a general repertoire of best practices, which, as a whole, is imho a lot more than just "coming back full circle".

    58. Re:Getters/setters bad? by arethuza · · Score: 1
      Good point.

      Surely the whole "but you may want to do something in a setter/getter" breaks the whole "You Aint Going To Need It" rule, which I tend to think overrides the "Blindly Apply Design Patters" rule.

    59. Re:Getters/setters bad? by jimm · · Score: 1

      That link again, without the extraneous space: http://www.javaworld.com/javaworld/jw-09-2003/jw-0 905-toolbox.html.

      --
      Transcript show: self sigs atRandom.
    60. Re:Getters/setters bad? by Anonymous Coward · · Score: 0

      ( I have not read the book yet )

      "Classic" getters are probably not that bad, although they can sometimes hardly be called OO. They are just of fancy way of looking at an object's internal state, which you don't need to do a lot of times.

      Classic Setters are a whole different ballgame. If your class is more than just a fancy data holding struct, implementing setters can make it very difficult to make assertions about the object and its behaviour. ( e.g. a car object with a "SetRpm" method -> bad -> the rpm should should be derived from other params : angle of pedal, gear, time, ... )
      It gets even worse when you put setters on a interface from which you derived classes. That way, you force every derived class to implement and satisfy the conditions of the setters. Sometimes a subclass cannot even implement the setter correctly ( e.g. interface IInteger with derived from it CZero. How would you make CZero implement IInteger::SetValue( int )?? )

    61. Re:Getters/setters bad? by mollymoo · · Score: 1
      At some stage the cart object will have to call: item.getPrice();

      I think his point is that you shouldn't call cart.addItem(), you should call item.addToCart().

      --
      Chernobyl 'not a wildlife haven' - BBC News
    62. Re:Getters/setters bad? by RetroGeek · · Score: 1

      So let's say the object suddenly needs to know that a field has changed (needs to set a flag or something, needs to notify listeners, etc). That does not affect the calling code but adds functionality.

      And designs change over time.....

      --

      - - - - - - - - - - -
      I am a programmer. I am paid to produce syntax not grammar. Deal with it.
    63. Re:Getters/setters bad? by bokmann · · Score: 2, Informative

      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.

    64. Re:Getters/setters bad? by alw53 · · Score: 1

      >A fundamental precept of OO systems is that an >object should not expose any of its implementation >details.

      So the implementation is exposed but not used? Or maybe the comment referred to novel meanings of the words "fundamental" and "expose", with which I'm not familiar?

    65. Re:Getters/setters bad? by Retric · · Score: 1
      Can someone explain why accessor and mutator methods (I assume this is what he means by "getters/setters") are bad?

      My guess is that in some instances, publically accessible getter/setter methods can be construed to be "exposing the underlying implementation" of a class. Of course, that just means you need to judiciously use getter and setter methods.

      Hmm, so don't make them all public? I agree that classes should only let you get and set things that are meaningful outside the class by things like Vector.getLength are needed for classes to interact. And private methods like window.setFontSize() are vary useful as they can check for valid data as they change the object's state.

      My guess is he wants you to have object's interact at higher levels so you use things like Dog. Jump vs. chains of actions like
      For (int x = -25; x < = 25; x++){
      Dog.setHight(ABS(25-ABS(x)));
      Dog.showLoc();
      }
      where it's not clear what your telling the other object to do.

      Anyway Nod: That's my guess at least. I suppose I should read the book.
    66. Re:Getters/setters bad? by killjoe · · Score: 1

      Typically the value objects don't really have validation logic. They are very lightweight so they an be shuttled back and forth from the server.

      --
      evil is as evil does
    67. Re:Getters/setters bad? by Ryosen · · Score: 2, Informative

      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".
    68. Re:Getters/setters bad? by achacha · · Score: 1

      My point is missed... the idea is that not every accessor needs to be a get/set method, some that will not need complex functionality behind it can just use the variable directly. This is a design issue more than anything else, and in the modern world of dev environments, refactoring is not too hard. Even with C++ this is not hard, just put the variable in the private: area and see what breaks and replace with accessor. If you do this too often then you are not deisgning the hierarchy correctly :)

    69. Re:Getters/setters bad? by achacha · · Score: 1

      That is my point, people blidly apply patterns to everything, which results in bulky, slow code. I used to think that getter/setter was needed for all members, but having used both, I think a balance is a nice thing to have. In some cases you want to expose the variable, in others you want to keep it in getter/setter pattern. It all depends on the design and how the object is going to be used. If the class is nothing more t han a placeholder for some data (ala C struct), then adding getter/setter is a waste and often good compilers will just compile out the method call and do it inline (but not all compilers are created equal).

    70. Re:Getters/setters bad? by RetroGeek · · Score: 1
      True, though I like to "encapsulate" the information.

      And creating getters and setters (at least in the Java Eclipse IDE) is a matter of RMB/ Source/ Generate Getters-Setters/ OK, for all the fields.

      And, AFAIK, modern compliers will optimize
      b = x.getName();
      to
      b = x.ivName;
      if the method getName() does nothing else except return the value. As for typing, the IDE will fill in the method name (CTRL-Space).
      --

      - - - - - - - - - - -
      I am a programmer. I am paid to produce syntax not grammar. Deal with it.
    71. Re:Getters/setters bad? by Anonymous Coward · · Score: 0
      This is not what Holub is arguing. Holub's argument is that only class Foo should access/mutate class Foo's member variables. In fact, only class Foo should even be aware of the existence of its member variables.

      You're describing two different ways that another class, say class Bar, can access/mutate Foo's member variables. One way is through getter/setter methods. The other way is through direct access to a public member variable. Holub argues that both of these violate the tenet of encapsulation. Class Bar should not be allowed to mess with class Foo's member variables. Class Bar shouldn't even know what those member variables are. Instead, Bar should call a method on Foo that requests that Foo do the work.

      A simple example would be displaying the value stored in Foo on the screen. Instead of Bar accessing the value using Foo's getter (or by directly accessing a public member variable) and then displaying on the screen, Bar would simply call something like Foo.displayStuff(), which would write to the screen everything that is necessary to be displayed.

      The purpose for that is that if later you decide that Foo should also have another member variable, the only place you need to make any code changes is in class Foo. If you allow other classes to access/mutate Foo's member variables, then adding that new member variable will mean visiting every class in the entire application that accesses/mutates Foo's variables and updating them to include the new member as well. This is precisely the sort of coupling that OO is supposed to minimize.

      The downside to this is that you couple your business logic with your presentation logic. However, Holub does have an article giving an example of how this can be done without tying presentation to business logic. I haven't read that article yet, so I won't try to explain it. I plan on studying that article soon, though, as I'm still on the fence about this issue, but I can certainly see the point he's making.

    72. Re:Getters/setters bad? by arethuza · · Score: 1
      I have to say that I have probably seen more problems caused by over-zealous application of patterns causing enormous bloat of systems than whatever the original problems were that Design Patterns are supposed to solve.

      Its not that I dislike the concept of design patterns, but their use requires an element of judgement that appears to be frequently missing.

      Oh well, I guess I won't be the only heretic burned then ;-)

    73. Re:Getters/setters bad? by fupeg · · Score: 1

      Sometimes data flow is necessary such as in the example you give. However, that does not mean that the only way to solve such a problem is a procedural solution. There are object oriented solutions to such a problem as well.
      The key concept is encapsulation. If you expose your attribute (price) to the whole world, then an unlimited number of clients can couple themselves to this, creating brittle code. So use a Builder pattern . Define an interface for exporting information about your Item object. For something like a Cart, define an interface for importing information (building) a Cart. Create a concrete class(es) that implements these interfaces.
      Notice that I'm not writing code here, I am designing. To most programmers (myself included!) that kind of statement seems pompous, but there really is a big difference in these two difficult tasks. This may also seem like too much work, too difficult, etc. It is definitely not the easiest/quickest way to solve the immediate problem. That's not the point of object oriented programming. The point is that it makes for code that is more robust and easier to maintain.

    74. Re:Getters/setters bad? by Anonymous Coward · · Score: 0

      That's why we don't call hash tables HashTables, we call them "unorderedBagsIndexedByArbitraryKeysWithConstantTi me Access", because that describes the PROPERTIES of the class rather than the IMPLEMENTATION.

      Except that hash table access is only O(1) with a perfect hash function. Worst-case complexity is actually O(n), in the hypothetical case where all keys hash to the same value. I think you can design the thing so that it's guaranteed to be O(1) amortized in non-degenerate cases, but that's, uh, an implementation detail... :p

    75. Re:Getters/setters bad? by Anonymous Coward · · Score: 0

      Beans were nothing but a simple hack to allow tools to work around the problem of Java missing first-class properties as language constructs (C# has them, thanks to Java and beans exposing the lack in all of its gory).

      No, C# has first-class properties because Delphi had them, and Microsoft hired the guy who designed Delphi to design C#.

    76. Re:Getters/setters bad? by Anonymous Coward · · Score: 0

      They've been available with Delphi(not coincidently the same designer for Delphi and C#) for hmm... about 6 years now? more?

      I believe they were introduced to Delphi with version 2 in 1996. That's going on 9 years now.

      Man, Delphi really deserved to catch on...

    77. Re:Getters/setters bad? by anomalous+cohort · · Score: 1
      If you design an object and mindlessly add get/set functions for every piece of private data in the object, then you're probably guilty of exposing the implementation. But if you design the object's public interface first, and decide on the private data afterwards, I would guess that you're probably in the clear to have used get/set functions "correctly." IMO it's not the functions themselves that are the problem, but rather the adherence to correct design principles.

      I agree entirely. Too much of anything isn't good. Holub is right on when he says don't make a design decision without considering the consequences. That is what design is about.

      Too bad he doesn't feel the same way about titles to articles. It shouldn't read Why getter and setter methods are evil, it should read Why exposed object state is evil. Here is the relevant excerpt.

      Getter and setter methods (also known as accessors) are dangerous for the same reason that public fields are dangerous: They provide external access to implementation details. What if you need to change the accessed field's type? You also have to change the accessor's return type. You use this return value in numerous places, so you must also change all of that code. I want to limit the effects of a change to a single class definition. I don't want them to ripple out into the entire program.

      So, it's not so much getters and setters because he doesn't want you to use fields either. Don't expose object state at all just ask the object to do something with its state. All well and good until it comes time to populate the GUI from the Problem Domain objects. You somehow have to get the widget's color to the JTextField or JspWriter or whatever. If it's evil to have either a Widget.getColor() accessor method or a Widget.color field, then you'll have to code a Widget.writeColor(JspWriter out) which is bad because it makes a dependency between your PD classes and your GUI classes. What if I wanted to reuse the same class for a client/server app? Never coding getters and setters is just as evil as always coding getters and setters.

      In the beginning, Booch said let there be class member functions and member variables. Member functions carry out an object's responsibilites and member variables contain an object's state. I've seen so called experts claim the member functions are evil and you should do everything via object state. Now, I have seen OO fashion go full circle. It's the member variables' turn to be evil and member functions get to wear the white hat.

    78. Re:Getters/setters bad? by Canberra+Bob · · Score: 1

      Could not agree more. One of the strong points of OO is reusability of code. This is achieved through each class taking care of itself, in total ignorance to how it is being used. Taking the shopping cart example (looking further I would just have a cart.add() method, rather than addItem() for reasons explained below).

      item.addToCart()
      Item object must know that it is being added to a cart. Item object must internally in the addToCart() method call Cart methods to add itself anyway - how else will the Cart have the object added to it? Modifying the way Cart is implemented will mean any object that adds itself to a Cart must also be changed. As in your example, what happens when we have an inventory? Shipment? What if we also sell services? We end up with an addToCart() method in class Item and an addToCart() method in class Services. A change in class Cart will create a lengthy hunt through all the other classes to see if they require changing - the problem OO was meant to solve. And we havent even touched on the nightmare that results if we subclass Item and override addToCart() (a very real possibility considering the many types of items that are likely to be in the system).

      cart.add(item)
      Item need not know that a cart object even exists. add() method can be overloaded to also accept Services objects for services rendered - Services class need not know that Cart object exists. Changes to the implementation of Cart class will not require modification of any other classes.

      I always try to visualise objects in terms of how they behave in the real world. An item has properties eg price. A cart has properties eg numberOfItems. The purpose of a cart is to store items, hence the method add(item). The purpose of an item is not to add itself to a cart, hence the method addToCart() should not exist in the item class. I can understand why getters / setters should be viewed with caution as read-only properties should never have a setter method, and write-only properties should never have a getter, but not using them at all tends to defeat the purpose of OO. Just my humble opinion

    79. Re:Getters/setters bad? by E_elven · · Score: 1
      inline int Foo::Bar() { return bar; }
      .
      --
      Marxist evolution is just N generations away!
    80. Re:Getters/setters bad? by Anonymous+Brave+Guy · · Score: 1

      I agree that composition should often be favoured over inheritance, but I think there are several reasons for this. The bottom line is that inheritance is most useful as a mechanism for allowing implicit type coercion via polymorphism. If you don't need to use polymorphism, inheritance is just another tool for organising your code, and it's often over-used in that context where simpler things like composition would avoid cluttering the class hierarchy, issues with anonymous base subobjects that could be named explicitly if they were members, etc.

      --
      If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
    81. Re:Getters/setters bad? by Anonymous+Brave+Guy · · Score: 1
      The key concept is encapsulation. If you expose your attribute (price) to the whole world, then an unlimited number of clients can couple themselves to this, creating brittle code.

      Do you often write a shopping application, and then find that the items for sale no longer have a price? Ensuring that the Price type is user-defined (if only as a synonym for double at first) should be plenty of future-proofing for now.

      So use a Builder pattern . Define an interface for exporting information about your Item object. For something like a Cart, define an interface for importing information (building) a Cart. Create a concrete class(es) that implements these interfaces.

      This may also seem like too much work, too difficult, etc. It is definitely not the easiest/quickest way to solve the immediate problem. That's not the point of object oriented programming. The point is that it makes for code that is more robust and easier to maintain.

      Newsflash: adding vast amounts of clutter around a simple concept does not make code either more robust or easier to maintain. Your design commits the cardinal sin of over-engineering based on a hypothesised future change requirement. You can't possibly know whether all that extra rubbish will make a future change easier, because you don't know what the change will be yet. However, you can guarantee that writing all the additional clutter will take longer, leave more scope for bugs, and make the code harder to understand if it does turn out that maintenance is needed later on. This sort of ivory tower theory is exactly why so much OOP code is unmaintainable junk in practice.

      --
      If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
    82. Re:Getters/setters bad? by jquiroga · · Score: 1

      I understand that is true in many situations. In fact, Holub himself agrees with you.

      ... I do believe that data flow should be minimized in a system, and that methods generally should not return basic types (with the exception of boolean), but there's certainly nothing at all wrong with a method that returns an object that implements a known public interface. ...

      Besides that, he tries to emphasize design process, to invite us to keep in mind OO principles while looking for an ideal design first, and to settle for something less than ideal afterwards, as late as possible. In a nutshell, if getters or setters are to be used, they ought to be included at the end of the design process, only if a better solution isn't found, but not at the beginning (that's what he regards as evil).

      I've tried his approach and the designs are much better than whatever I am able to conceive any other way (I'm not surprised). But it takes more effort and commitment, of course. And it takes longer.

    83. Re:Getters/setters bad? by alw53 · · Score: 1

      This would make sense if all Maps were the same, but obviously programmers pick one kind of Map because they expect it to have unique BEHAVIOR. Hash tables have O(1) access times. B-trees have log access time but have ordered keys. Vectors are only accessible by integers. If all types of Maps had IDENTICAL interfaces there would be no need for different implementations.
      ==
      To put it very simply: people design different data structures BECAUSE they BEHAVE DIFFERENTLY. Their BEHAVIOR IS DIFFERENT. You cannot treat them all the same, all the time, without paying a price.
      ==
      Make the interface as simple as you can. Don't worry about hiding the implementation. The only way of hiding the implementation of a hash table would be to add predicates (map.orderedKeys(), map.constantAccess(), map.integerKeys(), etc) and that would complicate the interface.

    84. Re:Getters/setters bad? by Anonymous Coward · · Score: 0

      Can someone explain why accessor and mutator methods (I assume this is what he means by "getters/setters") are bad?

      Well, the objects are supposed to fullfil their responsibilities, not expose their state for some other object to act on. So, if you use the accessors, you aren't really doing OO and the classes then act just as structs.

    85. Re:Getters/setters bad? by NoOneInParticular · · Score: 1
      OO has nothing to do with data hiding, it has everything to do with data protection: you want to know at every point in your code that the data in the object is in a meaningful state. This meaningful state is called the invariant of the class. I you cannot state an invariant for a collection of data, you either think harder or make the data publically available. Data hiding is not an end, it is a means of making sure that the invariant is maintained. If there's no invariant, there is no use for data hiding. Classes without an invariant are usually the ones that need getters and setters: in that case, just make the data public and be done with it.

      Constructors establish the invariant and methods are the only functions that are allowed to temporarily destroy the invariant to achieve a new state. As long as they re-establish the invariant when they return you're ok. All functions that manipulate the object, but don't need to touch the invariant (i.e., can work by using only the methods), should not be methods themselves, but should preferably be put in in a library.

      Good OO design recognizes that OO is not the solution to all problems, it is however a damn good solution for a specific set of problems: managing data with strong interdependencies and relationships. Maintaining these relationships is all a class should do. No more, no less. The rest is handled by simple functions. The way Java is usually taught and practiced breaks this very simple idea in so many ways and at so many levels that it really isn't funny anymore.

    86. Re:Getters/setters bad? by ph1ll · · Score: 1
      Apart from being bad OO (read the book or see Holub's article in JavaWorld), another problem he does not mention is hash code generation.

      If you use your object as a key in a hash then change it's members, it will probably mean your hash code value changes (depending on how you generate it). You may then find that your object does not correspond to the value for which it was the key in the hash table.

      Regards.

      --
      --- "We've always been at war with Eastasia."
  4. Applicability to other forms of development by nanter · · Score: 4, Interesting
    Object oriented patterns are great, and there have been numerous books written that have covered some of the most valuable OO patterns in use. I've recently started work in service oriented architectures, however, and I've noticed that shifting from an OO mindset to an SOA mindset can at times be more challenging than the switch from procedural to OO. Given that the guts of the web service implementations are often in OO, and these patterns can thus be applied there, has anyone seen any good treatises on SOA patterns yet, be it online or in book form? What I've seen has been pretty preliminary and basic. Given the immaturity of SOAs and the thusfar slow adoption of them, it's not surprising, but it would be nice to have some 'pattern gurus' apply their skills to both SOA patterns and the interaction between SOA patterns and the existing OO patterns.

    In the interim before the appearance of such works, I've been trying to keep an informal list of patterns I've unearthed through practice, but my ability to codify patterns cannot match that of someone like Holub. :-)

    1. Re:Applicability to other forms of development by Anonymous Coward · · Score: 0

      There are plenty: http://www.google.com/search?hl=en&q=%22design+pat terns%22+%22service-oriented+architecture%22&spell =1. You might also want to try restricting the search to ibm.com, as they have several several articles on this.

    2. Re:Applicability to other forms of development by rffrff · · Score: 1

      and the funny thing is that the original OO patterns are 90% oneliners or simple language features of common lisp, or unneeded for some other reason. Go figure.

  5. Homestar quote... by PMJ2kx · · Score: 1

    Finally, the book closes with an appendix that gives more typical recipe-card style listings of all the design patterns discussed throughout the text.

    What? Is that supposed to be some sort of witch's brew?

  6. sounds promising by magicmonster · · Score: 2, Interesting

    This sounds promising. I've been waiting for another book besides design patterns by the gang of four, and specifically looking for one with nice Java examples. The other design patterns books I've found are all geared towards J2EE or the enterprise market. Does anyone have a quick table of contents or a list of patterns he covers?

  7. Re:goat.cx links above. by Anonymous Coward · · Score: 0

    LMAO! Well, MISTER HACKER try typing gmail.google.com into your browser and see what happens.

  8. Re:goat.cx links above. by numatrix · · Score: 0, Offtopic

    huh? Actually, the 'real' gmail is gmail.google.com. Check out the ssl cert for https://gmail.com/ if you don't believe me. I imagine it's done that way so all the google domains share the same cookie base.

  9. Re:goat.cx links above. by Anonymous Coward · · Score: 0

    Shit dude did you just hack Google? I'm getting the Gmail page!

  10. Check out "Pattern Hatching" by John Vlissides by Eric+Giguere · · Score: 3, Informative

    Design pattern fans should check out Pattern Hatching: Design Patterns Applied by John Vlissides, one of the Gang of Four. Short, but interesting reading.

    Eric
    How to detect Internet Explorer
  11. Re:goat.cx links above. by Anonymous Coward · · Score: 0

    YHBT YHL HAND.

  12. Re:Bring back procedural languages by Anonymous Coward · · Score: 0

    OOP fails and will always fail because it attempts to anticipate the future at design time, and that's just plain silly.

    No, your OOP attempts fail. I can't see anything in your post that applies to OOP versus any other style/method of programming.

  13. Re:Bring back procedural languages by Anonymous Coward · · Score: 0

    No Commodity Server for me. It's all a bunch of "if-then"s with nothing underneath.

  14. Re:goat.cx links above. (propz2penisbird) by Anonymous Coward · · Score: 0

    lol, people like you are the reason why I keep trolling. you think I dont know that? the troll is in the fact that a whole bunch of you come in here to tell everyone the truth and then make a big rucas about it. its so LOL to watch 5 or 6 of you make a big fuss.

  15. Re:goat.cx links above. by Anonymous Coward · · Score: 0

    Google owns gmail and uses the google.com subdomain for gmail stuff.

    You're an idiot.

    I bet you don't have the balls to reply and admit that you are wrong.

  16. Comment removed by account_deleted · · Score: 1

    Comment removed based on user account deletion

  17. Another pompous "expert"? by Anonymous Coward · · Score: 5, Informative

    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:

    double orderTotal;
    Money amount = ...;
    //...
    orderTotal += amount.getValue(); // orderTotal must be in dollars

    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:

    orderTotal += amount.value

    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:

    total.increaseBy(amount );

    But this is just syntax. In Ruby I would just write:

    total += amount

    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???

    1. Re:Another pompous "expert"? by orcus867 · · Score: 1

      You are confusing accessibility with responsibility. Using the money example, it is better to have the Money class increase the amount instead of having someone else do it. As in your example, Money.increaseBy(float), or even Money.add(Money), is more maintainable than orderTotal += Money.getAmount().

      It's perfectly fine to have a Money.getAmount() : float, but do not have a Money.setAmount(float). If you need to set the amount, create a new Money object, new Money(float).

      If you want a universal way of getting the value of money, then do Money.getAmount() : String. Not only does it allow you to display it, but it hides the underlying implementation.

    2. Re:Another pompous "expert"? by AllenHolub · · Score: 1
      To take the matter even further, what if you need to add the notion of "currency" (dollars, yen, etc.) to Money? A getValue() method is even more problematic in this situation, becuase you don't know whether the returned number represents dollars, yen, or whatever other currency is supported. Adding a getCurrency() opens up a huge can of worms because you'll have to be doing currency conversions all over your code. The Money.add(Money) approch takes care of this problem by doing the currency conversion internally.

      Also, re. the Kruger and Dunning article (at http://www.apa.org/journals/psp/psp7761121.html). It's really worth reading. Their point is that smart people have a hard time seeing what they do and don't know. I certainly fall into that trap on occasion myself, as do most of us.

    3. Re:Another pompous "expert"? by tolan-b · · Score: 0

      Oh please get over yourself.

      There's a very good reason for statically typed languages. They promote code that is more reliable. If you're expecting a particular return type from my API then you should be able to be confident that that is what you'll get, otherwise someone else's fuckup can introduce bugs into yours without you even knowing. Being able to add a to b is fine until c returns a Car. How many is 6 + Honda?

      Dynamically typed languages are great for rapid development. I use PHP5 for a lot of smaller developments, because it strikes a nice balance between speed of development and safety. However if I need to develop a large reliable system I would choose Java over something like PHP or Ruby every time.

    4. Re:Another pompous "expert"? by Anonymous Coward · · Score: 0

      6 + Honda is a TypeError, which was caught by your test suite. Don't confuse "weak" typing with "dynamic" typing. Weak typing (as in PHP or Perl) pretty much sucks; strong dynamic typing (as in Python or Ruby) does not.

      Besides, type errors are trivial and easy to eliminate; it's the logic errors (or, in a C/C++-style language, the memory handling errors) that are insidious.

    5. Re:Another pompous "expert"? by MarkusQ · · Score: 3, Insightful

      I think you are missing his point. In ruby, as in SmallTalk, or any other real OO language, "+=" is just a message (in this case, one that is automatically defined when you define "+"), to say that it's better or worse than another semantically equivalent message is just silly.

      Yes, they are semantically distinct in Java, but that is a statement about Java, not about OO programming.

      -- MarkusQ

    6. Re:Another pompous "expert"? by MarkusQ · · Score: 2, Interesting

      Strongly typed != Statically typed

      You are confusing two concepts here. Smalltalk, for example, is dynamically typed yet it doesn't have all the casting about that C does; the typing is strong and dynamic while C's is static and weak/leaky. What gets you into trouble is the weak/leaky typing, not the dynamic typing.

      -- MarkusQ

    7. Re:Another pompous "expert"? by Anonymous Coward · · Score: 0

      in your example, Money.increaseBy(float), or even Money.add(Money), is more maintainable than orderTotal += Money.getAmount().

      Why? Maybe orderTotal is a Money object to begin with. If you're not dealing with static typing it doesn't matter.

      Maybe it started life as a Float and is now a Money object with a currency and everything. No need to worry if you're dynamic.

      If the author's point is that exposing the *type* of the amount is a bad thing, then yes, that's true. But in a dynamically typed language it doesn't matter unless you're doing silly things like checking types. You don't have to change the client code when refactoring.

    8. Re:Another pompous "expert"? by Anonymous Coward · · Score: 0

      How does Money.add(Money) vs. Money.getValue() solve the currency problem? You still have to go back and edit the client code to add currencies to the Money objects you want to add. You've just changed the semantics of Money objects, there's no way the code can remain unchanged if your classes are changing their *meaning*.

      A better question might be, what if getValue() returned a funky FixedPoint class instead of a float? Then in Java you're stuck with some work to do but in, e.g., Ruby you might not be.

      The point should be, is a "value" something you expect to get and set from a Money object? If so, then there should be a getter/setter. If not, there shouldn't be.

      Personally I would always treat Money objects opaquely, for the reason you mention: currencies. Same with any number that uses units.

      But if it's a Customer object's firstName() then I will feel no remorse in using getters/setters.

    9. Re:Another pompous "expert"? by Anonymous Coward · · Score: 0

      You are confusing two concepts here. Smalltalk, for example, is dynamically typed yet it doesn't have all the casting about that C does; the typing is strong and dynamic while C's is static and weak/leaky. What gets you into trouble is the weak/leaky typing, not the dynamic typing.

      Wrong. Weak typing is dangerous because it does not automatically generate an error when mixing incompatible types.

      Dynamically typed languages are usually strongly typed but do not help you catch bugs in your code. With a statically typed language (like Java) tools can automatically find your bugs for you before you even compile! (Eclipse does this for example)

      The problem w/ dynamically typed languages is that you cannot find bugs with static analysis tools (as easily) because there is a lack of formality in your code (type declarations).
    10. Re:Another pompous "expert"? by Anonymous Coward · · Score: 0

      Definitely a pompous expert, as you so rightly put - although I think the main thing he is trying to say is that too many classes out there are not following the key OO tenet of encapsulation, i.e. don't expose all of the attributes in your class - distinguish what ought to be private, and what ought to be public etc. (although there are definately going to be practical tradeoffs). If you're doing that, then you've really missed the OO-boat, and will need more than this book to help you out!

    11. Re:Another pompous "expert"? by AllenHolub · · Score: 1
      Actually, even names can have problems. getLastName(), for example, isn't culturally universal. In many Arabic countries, what we would think of as a "last name" is actually the father's name. More over, the same person can be identified in more than one way (roughly translated as "father of" and "son of"). Two different "last names" can identify the same person! Exposing a "last name," then, could cause problems when you try to move your application to a country that uses these naming conventions. Even comparison becomes difficult becuase you have to determine that two seemingly different names actually identify the same person!


      Admitedly, this is all probably hair splitting for you average shopping-cart application. My point is that the side effects of exposing any implemenation details can be unobvious.

    12. Re:Another pompous "expert"? by Anonymous Coward · · Score: 0

      I think Holub's point on accessors is a little more strong than you make it out to be.



      If you expose the amount as dollars, it is not just that it is a float versus an int or some other type. It is that now you have a value that you can manipulate outside of the owning object, without restrictions. Once I have "pulled" the dollars out, I can increase, decrease, apply taxes to, convert to other currencies, and so on. For any of those operations there may be system/business rules that restrict how those calculations should be done--for example, when a calculated value should be truncated (and at what point) and when it should be rounded. Now those rules must be applied in all the code manipulating dollars, outside of the Amount class.



      I think what Holub is warning against is treating objects as if they were uncontrolled structs, which just hold values that are passed around between modules that need them. We already have that practice--it was a standard over two decades ago. The inability to maintain and extend those systems easily was one reason OO became popular.



      The downside of Holub's approach, which he recognizes, is that you have to design those manipulation APIs in advance, which leads to a longer design cycle.



      About his problems being Java-specific--Holub has been a software engineer for well over 20 years. He has books on C, writing C compilers, C++, as well as Java. He apparently also worked on robotic systems early on, as well as in assembler. He wrote the C Toolchest column in Dr. Dobbs Journal for many years. By his own admission, he sticks with Java because he likes it, not because he has to.



      Patrick
    13. Re:Another pompous "expert"? by CrazyWingman · · Score: 1

      Whoever modded this post as +5 Informative is a fucking moron. The guy admits he doesn't know Java, and yet he makes arguments about how Ruby is better than Java. The way he talks about primitive types, you would think he thought there was a "dollar" type in Java. The purpose of the comment in the code is to remind the programmer that he wants the value in dollars, not billions of dollars, euros, yen, etc. The only thing the post is +5 informative about is how much of an idiot the poster is (and maybe how stupid the modders are).

    14. Re:Another pompous "expert"? by MarkusQ · · Score: 1

      The problem w/ dynamically typed languages is that you cannot find bugs with static analysis tools (as easily) because there is a lack of formality in your code (type declarations).
      If you don't have the option of aliasing, casting, untagged unions, etc. in the language either, your point may well hold. As it stands, strongly typed languages generally leak (allow the programmer to "get around" the formal specification) more than dynamically typed languages--enough so that there is no net advantage.

      Plus, while static typing catches some errors (e.g. string vs. int) it generally doesn't catch others of the same sort (prime int vs. non-prime int) and encourages the programmer to ignore them. Thinking of all such errors as either "value errors" (strong checking) or "interface errors" (duck typing) and dealing with them in one go gives, IMHO, better, more consistant results.

      -- MarkusQ

    15. Re:Another pompous "expert"? by elbobo · · Score: 2, Interesting

      Indeed. The irony is the comment opened with a negative reference to a paper on how people with substandard knowledge often presume themselves to be more capable than they are. Looks like he walked right into that one.

    16. Re:Another pompous "expert"? by tolan-b · · Score: 1

      I'm not confusing weak typing with dynamic typing.

      Personally I dislike both in principle but am willing to put up with them for speed of development. *AS LONG* as I'm working with people that can find the right end of a cluestick..

      Weak typing for example is a real boon to code simplicity when working with the web.

      Yeah yeah, I write all my tests before my code honest, and yes there's always 3 of us sat round my monitor. But back in the real world, in my experience type errors are the sort of thing most likely to slip through the test suite.

      Contrary to popular wisdom I find that actually it's supposedly trivial errors that are the hardest to track down, and the most likely to end up biting you on the arse 3 months after deployment.

  18. Re:Bring back procedural languages by GlassHeart · · Score: 2, Insightful
    Just because code isn't object-oriented doesn't mean it's bad code, and anybody who tells you otherwise is just being dogmatic. However, there's a good chance that such code is less well-isolated from the rest of the system, and your one-liner fixes can more easily introduce unintended consequences.

    One common pattern with maintained code is the cancerous growth of special cases to deal with new requirements. Over time, the special cases dwarf the original code, and it becomes very hard to even figure out what it's supposed to be doing.

    Yes, OO doesn't solve all problems, yet "procedural languages"* are also well-known to have many problems of its own. OO is also easy to get wrong, as evidenced by your "have to throw them away periodically" observation. However, I can't help but feel that you're making conclusions based on limited and anecdotal evidence of failures.

    * Many OO languages are procedural.

  19. Re:Bring back procedural languages by Greyfox · · Score: 2, Interesting
    Well the reason the technique was originally invented was that the DOD was spending way too much money on software maintenance. Of course, they were trying to maintain millions and millions of lines of Fortran, COBOL, BASIC and Assembler. Who's to say that improvements in structural techniques over the past decade or so wouldn't also have solved those problems?

    Anyway, what I've noticed is that up until the past couple of years, not many people really had an idea of how to do Object Oriented programming all that well. Most programmers were faking it, mimicing the talk out of the various trade rags without really understanding the reasoning behind what they were doing. And you can make some pretty atrocious object oriented designs if you don't know what you're doing.

    OOP doesn't need to be what you've seen any more than procedural code needs to be twisty mazes of GOTOs and global variables. It all boils down to the abilities of the guy writing the code.

    --

    I'm trying to teach myself to set people on fire with my mind... Is it hot in here?

  20. Re:Bring back procedural languages by BadDream · · Score: 1

    OOP done badly is as you describe, but done well, can be amazing.

    The same crew that uses OOP badly may also use any other methodology badly. I have wasted countless days reading through nested if-then statements trying to figure out how something works. And when you find out, the user tends to not want that to be the case, and you rewrite it anyway.
    That is is the road to insanity.

    --
    No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style.
  21. Re:Bring back procedural languages by guitaristx · · Score: 2, Insightful

    OOP is a wonderful thing because it enforces tons of those wonderful principles that are taught in Computer Science classes 'round the globe: encapsulation, abstraction, data hiding, "black-box" programming, etc. OOP is NOT supposed to be the end-all, be-all of programming, just as the creation of C and other higher-level programming languages was not to be the death of assembly programming.

    What, so often, people fail to realize is that software is designed to be built in layers. See the TCP/IP stack, for instance. This allows for one of those wonderful OOP principles to work - abstraction. If the nature of the OOP system/API/et. al. is causing you more problems than it's solving, then I say it's not OOP's fault, it's the designer's fault. I don't believe that OOP is the solution to all problems - some problems are square, and some programming paradigms are round. Problems arise not because of the evil nature of OOP, but because someone tried to pound a square peg into a round hole. OO languages and systems give you the ability to make things object-oriented, but none that I've seen prevent you from using procedural programming techniques when your square programming problem doesn't fit nicely into a round OO hole.

    Generally, I've found that people who hate OOP were forced into using it without getting enough exposure to it to appreciate it. Nobody's gotten rid of procedural programming, just like nobody's gotten rid of assembly programming. We just have higher-level tools and paradigms for dealing with high-level programming tasks.

    --
    I pity the foo that isn't metasyntactic
  22. Should be titled "Holub on Java Patterns" by pammon · · Score: 4, Insightful

    The dirty unacknowledged secret of design patterns is that they're strongly coupled to a language. For example, switching from a statically typed language like Java to a dynamic one with forwarding substantially changes the approach to Factory, Proxy, Singleton, Observer and others. In fact, they're often rendered trivial. The claim that the approaches described in the book apply to any language is just not true. These patterns are for Java and Java-like languages.

    1. Re:Should be titled "Holub on Java Patterns" by gh · · Score: 1

      The only aspect that really is tied to a given language is how you go about implementing the pattern. The usage of the pattern, where it would be used in code, should have very little bearing on the language. If there is any bearing on the language is that the languages that make it easier to use the pattern, you're likely to see that pattern applied more often in solutions.

    2. Re:Should be titled "Holub on Java Patterns" by pammon · · Score: 2, Insightful

      Patterns are often applied as a substitute for missing language features. Using the Decorator pattern makes little sense if you can add methods and variables to individual objects (like in Python or Self).

    3. Re:Should be titled "Holub on Java Patterns" by rivermaker · · Score: 3, Interesting

      There is a good presentation on how the dynamic languages make the patterns trivial/unnecessary; written by Peter Norvig. Check out http://norvig.com/design-patterns/

    4. Re:Should be titled "Holub on Java Patterns" by SEWilco · · Score: 1

      "This is your Holub on Patterns"
      Any questions?

    5. Re:Should be titled "Holub on Java Patterns" by Bbazzarrakk · · Score: 1

      Are you aware of the "singleton", "observer" and "delegate" libraries in Ruby's Standard Library (included with the language install)? Ruby is a dynamic language.

  23. Try Perl's non-OOP equivalents by onlyjoking · · Score: 2, Informative

    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

  24. Because OOP Has No Mathematical or Logical Basis by Anonymous Coward · · Score: 1, Interesting
    OOP is the biggest waste of money ever to visit computer science in history. We spend bazillions of dollars to build these giant hierarchies, and then, have to throw them away periodically because they are too rigid...
    All OOP models are unique and therefore different. It is impossible to find a single basis for all possible OOP models. It is often not possible to change an OOP design without restructuring objects and code heavily. Ergo the brittleness of OOP design. This is a fatal weakness to OOP and indeed will lead eventually to it's abandonment.

    In a similar manner object-oriented databases have no mathematical or logical model (wherein one can model any OO database ) and so the relational database model, which can be universally applied to any database and which has a strong mathematical foundation, dominates.

    Someday OOP proponents will realize the futility of their efforts and move to logic programming systems. But such systems are somewhat difficult to master today (look at Prolog) and will need improvement before adoption becomes widespread. Today's "business rule" systems are a sort of hybrid OO-logical mixture that has significant market share.

  25. What about multi-tier? by Spy+der+Mann · · Score: 1, Interesting

    If it wasn't for OOP, we probably couldn't have reached multi-tier approach to programming. Yes, I know, Java sux. But not OOP in itself.

    I program in PHP, and without OOP, I wouldn't be able to use very nifty template classes which simplify my web job, not minutes or hours, but days.

    The problem with OOP is that if you don't know best-use practices and think before writing (i.e. use UML), you're sure to make a bloody mess.

    Think of OOP as 3D as procedural programming was 2D. A building in 3D is certainly more astounding than a 2D plane. But a maze in 3D is much scarier than a 2D maze.

    It's not that OOP is "worse" than procedural programming. It just allows more powerful designs (either good or bad).

    1. Re:What about multi-tier? by Anonymous Coward · · Score: 0

      Not to denigrate Communism, but this is exactly what people said about Communist states whenever they didn't work. IE Russia wasn't "really Communist", China was "true Communism", etc...

  26. The examples sound great, but... by javaxman · · Score: 4, Interesting
    I'd like to see the details of the first section.

    I mean, yea, "getters/setters are bad", in public APIs. Getters are bad- unless you need to vend an object and can't afford the overhead of creating entirely new instances when you do so. Setters are _definitely_ bad- unless they're private or are data that act as input for your object, which it recieves from controller-layer objects.

    Sure, "inheritance is dangerous" as anyone who has ever written an object-oriented program from scratch and had to modify it can tell you. Inheritance is also the key to code reuse, and can be very powerful when done correctly- do you really want to re-write a section of logic that's shared by 5 other objects ?

    These things have their place. They're good targets for "is evil"-type articles because they're often used when they should not be. But to call them "evil" and "bad" without proper qualification? It smacks of unprofessional behavior, at best.

    I'm a bit puzzled by claims that use of getter/setter methods and, more puzzling, inheritance, are indications that you haven't solved your problem in an object-oriented manner, or that your problem isn't object-oriented... because, well... not all problems are best solved by object-oriented methods, even if you're using an object-oriented language to do so. Sometimes, you need a variable and a loop... what's wrong with that?

    At some point, my model code is going to have to give my view code some objects to display... what, I'm not supposed to use getters there? At some point my view code is going to want to tell my model code about an object the user modified... I'm not supposed to use a setter there? I often think folks who write such blanket statements as "accessors are bad" are just trying to spark some flames.

    1. Re:The examples sound great, but... by Anonymous Coward · · Score: 0

      The types of claims Holub makes here seem to be common among Java-heads. It's understandable within their realm because they so often work with massive heirarchies of tightly coupled classes with numerous levels of inheritance every direction you look. Just look at the basic libraries. And just try adding functionality. You can't subclass a class without having to do the same with 5 or more others, to create your own little bubble of functionality. Java-heads seem to be obsessed with objectizing everything. This introduces its own level of inherent complexity, and so it's very easy for Java code to get too complex. As the parent said, there needs to be a level where you switch over from juggling objects and data to issuing sequences of instructions. Finding the right place to put that boundary can take away a lot of the problems that Java-heads are so terrified of.

    2. Re:The examples sound great, but... by Anonymous Coward · · Score: 0

      Object-oriented programming should really be called Politically Correct Programming. It's a great arena for argument about silliness like whether Interfaces or Inheritance are "truly-object-oriented". Smart people like Tarjan develop near-constant-time data structures like splay trees. Then the OO programmers, who could never have invented it themselves, get to justify their existences by arguing over whether it exposes the correct interface. Much easier than real work.

    3. Re:The examples sound great, but... by javaxman · · Score: 1
      You can't subclass a class without having to do the same with 5 or more others, to create your own little bubble of functionality. Java-heads seem to be obsessed with objectizing everything.

      Well, to be fair, I'm not sure you're right. I've personally used "extend" to do all sorts of good things in Java. Often the subclass is simple and just adds one or two methods. Why would you have to subclass other classes just because you subclass one, again?

      If someone writing in Java seems obsessed with making objects of everything, that's because in Java, everything is an object, with the exception of a few primitives ( which have object wrapper classes )... so in a sense, you have no real choice. If it's more complex than an int or float, you're talking object- there ain't no 'struct'.

      Heck, even when you create *any* object, you're using 'extend', on the class "java.lang.Object"! The trick is to come up with a design that models your problem well, and break the problem in to tiny pieces the _first_ time, so you don't end up 'refactoring'.,, which basically means you didn't do a good design the first time. Which is typical. Knowing what to do before you start working on something is difficult, to say the least. That problem has nothing to do with OO or even programming, specifically, it's a problem with design and implementation of any system. Nobody builds a car from scratch on the first try without a few subsystem redesigns.

      Having said that, just because you have to refactor doesn't mean you have to throw away your old API, you can wrap your refactored classes inside a 'compatability' class which supports your 'old' code. Again, I think the problem ( and danger , and badness ) of accessors and subclassing is being overstated to fan flames and attract traffic.

    4. Re:The examples sound great, but... by Anonymous Coward · · Score: 0

      I can tell you from experience (I've met Allen Holub on an occasion or two) he would attack your assumption that MVC is good and that is should be allowed to influcence the rest of your code. I've observed many reactions to this (I now like to make the same gripe, for fun and profit) going from but, but MVC is good to "but, it is from small talk". Bottom line, MVC is a shitty pattern because it forces you to write those getters.
      The alternative (GASP!) is having rendering code in your business objects (BUT, BUT THAT IS BAD RIGHT?), which isn't so bad so long as your rendering is to something generic like XML. A phone number is a phone number, whether you put it in a GTK+ Widget, HTML form, Swing, whatever, and the same attributes will be relevant. Don't confuse "view" with "put it on the screen" and your life will be better.

    5. Re:The examples sound great, but... by Anonymous Coward · · Score: 0


      Inheritance is also the key to code reuse, and can be very powerful when done correctly- do you really want to re-write a section of logic that's shared by 5 other objects ?


      Holub and others like Peter Code would say that inheritance is NOT the key to reuse. If all you want is reuse, use composition.

    6. Re:The examples sound great, but... by Bbazzarrakk · · Score: 1

      Sure, "inheritance is dangerous" as anyone who has ever written an object-oriented program from scratch and had to modify it can tell you. Inheritance is also the key to code reuse, and can be very powerful when done correctly- do you really want to re-write a section of logic that's shared by 5 other objects ?

      You misread the review. It doesn't say inheritance is dangerous. It says subclassing is dangerous. Subclassing is one form of inheritance, but not the only or even the most useful form.

      I think you need to read Holub's book. ;)

  27. Intuitive by roman_mir · · Score: 5, Interesting

    I didn't find it in many programmers I worked with, but personally I find all of the advices in this book intuitive. What I did find in many programmers is the rigidness they assume when someone questions their position on some specifics. I remember a few conversations I had where I questioned the entire OO paradigm, the people look at you as if you are mad.

    But the reason why I questioned the OO paradigm was not the paradigm in its purity, but the implementations that I so often saw in real life. Some of the architectural designs that I witnessed did not make any sense and were artificially created to be more complex than the problem at hand required. What is worse, I have seen 'architects' who got into those positions without any merit. I have witnessed architects who think their position is justified because they spend another 4 weeks in the beginning of every project 'rethinking' the ACLs. I have witnessed an 'architect' that was supposed to design a system, but who instead sat down with a programmer, did a bunch of handwaving, and left the programmer without any idea and without documentation on how things are supposed to be done, and it was not a simple thing for that guy who was still a beginner. I cannot count the number of times where I (as a contractor) in different companies was put into a position where I had to solve the problems created by these 'architects' as well as by 'managers' and the marketting people.

    Yes, I remember having a conversation about getters, setters about 4 years ago, I was convinced that those things are a horrid idea as well as extends (for almost the same reasons given in the article). I was attacked on more than just the techno-level. It is hard, it is not easy at all to work around bad design decisions, where someone just does something because it is either a pattern they read, or the marketting says it has to be done that way because there was this meeting with an IBM guy, who bought all the managers year-long golf memberships.

    What I appreciate in people is the ability to think for themselves and to make decisions on when something is appropriate. I am also a realist, I know that noone on this planet can be perfect 100% of the time. We get tired, we have schedules, we just want to do things fast and dirty, we resist structure because it is easier that way. But those of us who are good enjoy going through all of this nonsense and figuring out sensible ways to still deliver a good system.

    1. Re:Intuitive by elbobo · · Score: 1

      *shakes head*

      Done patting yourself on the back yet?

      Why is it that in every OO thread there's always one of these no substance, self congratulatory comments that hits +5?

    2. Re:Intuitive by roman_mir · · Score: 1

      simple, some people identify with such posts, unlike you.

  28. Re:Good book by Anonymous Coward · · Score: 0

    Or save even more by using Bookpool...

    http://www.bookpool.com/.x/7mg7fyzjlr/sm/1590593 88 X

  29. Re:Bring back procedural languages by roman_mir · · Score: 1

    Nothing is perfect by the way.

    In my last project I had a moment in between the deadlines, where I was able to actually do some OO design for a piece of functionality in the system. (a java GUI playing talking to C++ over JNI and playing videos.) The functionality I needed to add was an on screen display for video properties (you press up, and the current property is increased by 1, you press pgup, and you go to the next property, and all of this is overlaid on the video display.) So I had a choice. I could do it in the quick and dirty way, or create each property as an object extended from the base property, and then from one of the possible 2 property types: numeric and enumerated (strings). Each device listed which properties it has - some properties are common to some devices. These devices implemented interface that allowed to have a device factory to figure out which of the devices is playing right now. Once the factory retrieves the correct device manager, the device manager 'knows' the currently selected property. The property 'knows' it's min/max/default and the current value. The property 'knows' how to 'increase', 'decrease' its value by a step of 1 or whatever.

    And what do you know, the system became so robast that once in place, adding a new property or a new manager even literally takes 2-3 minutes.

    Now, implementing it through a bunch of if or switch statements would have created a maintenance mess.

    So no, I do not agree that OO is a complete waste of money. I do agree that in most cases the projects written in languages that allow OO are not written in the OO way, but rather in a procedural manner that is easier to think about and to develop but harder to maintain.

  30. There's some truth in what you say by lordpixel · · Score: 1

    There's some truth in what you say, but you're overstating it. Some patterns fit more easily in some langauges, and indeed some are unnecessary in more dynamic languages.

    However, the original Gang of Four patterns book rather disproves your assertion:

    " The dirty unacknowledged secret of design patterns is that they're strongly coupled to a language. "

    The examples in that book are all given in C++ and Smalltalk, which are pretty much at opposite ends of the O-O spectrum, and yet the patterns are applicable to both languages and also to Java and C#.

    There are probably patterns out there that only make sense in one language, and many are "better" or "easier" in lanague X or language Y, but I've seen little evidence that the majority of patterns are only useful in one language, and plently of evidence they're broadly applicable.

    For some patterns I doubt you even need an OO langauge.

    --

    Lord Pixel - The cat who walks through walls
    A little bigger on the inside than out

  31. Re:Bring back procedural languages by LordByronStyrofoam · · Score: 2, Informative

    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 /. it generates a warning about a badly formed comment.
  32. Head First Design Patterns? by Anonymous Coward · · Score: 0

    Timothy, you going to cover this book? I've like to see how the two compare. -TF

  33. Re:Bring back procedural languages by svin · · Score: 0

    Every time I sit down to a piece of "bad" old code, I notice just how much easier it is to maintain. I add an "if-then", but the OOP guy is screaming factor-factor-factor so much that you have to shlep the whole thing off to india to because that's the only way you can afford the thousand programmers to sort out.

    You are aware of the fact, that most OO languages have the (really usefull) if-then construct. If you only need to change that, it can also be done quite easy in those languages.

  34. Good post. by falzer · · Score: 0

    *Polite Golf Clap*

  35. (not) Short Plain-English Version Answer by IBitOBear · · Score: 2, Interesting

    Ok, to summarize his point. If you are making a "thing" then the operations on that thing should be contained inside that thing. So if you make these little routines that do nothing more than let you peek into "thing" to see "the real thing" inside, your "thing" isn't your friend.

    As a peice of mental oragmi (and to fold my own self in here, instead of _just_ trying to paraphrase this guy).

    There is nothing wrong (IMHO) to exposing parts of your thing via accessors and setters AS LONG AS you think of these methods as "translation to the outside world".

    That is, if you find yourself writing NewThing.setValue(OldThing.getValue() * 5) then you are no longer getting any useful work out of having "thing" in the first place, and this is bad. It's bad because you are requiring yourself/the world to reach behind a blined and operate on something that you hope will remain stable.

    Accessors and Setters are "good", however, (my view, not his) when you lear to see them as moments-of-control that you wrap around the need to communicate "parts of thing" with the outside world. These moments of control may involve locking or provide you the opportunity for "lazy evalutation" of a "thingness" that might exist in any of several forms. For instance, in TCL all of the values exist as this mutable state of "string or whatever". If you are working with the value as a string then it is best represented internally as a string; if as an integer then as an integer; etc. So having a getValueAsString() and getValueAsInteger() accessors make sense as they have that opportunity to do things while communicating with the outside world.

    Such an enlightened thing should, however, have a [+= int] operator, and that operator should be used in global preference to dong set(get()+X).

    So it isnt "really bad" to offer the user the opportunity to communicate with your object, but if you find that the objects *prefer* to be tweaked via this communication, then you have made a mistake that will cost you a lot _eventually_.

    In practice, you can avoid this trap by being liberal with the getters but stingy as heck with the setters.

    For instance a network socket object should have a lot of getters for things like "local address" and "peer address" and "lcoal port" and "general health"; but you don't want to "set peer address then connect" you want to socket.connectTo(PeerAddress).

    Anoter example is "const string & someImportnatValue()" where your object maintians some important string and you might want to let the world examine that important value. But you don't ever let the world "replace" that value whole-scale. You allow the world to opperate uppon the thing, which *may* change the string too.

    So expose spesific items of interest through accessors, but only provide "operators" as a means of changing what must change.

    After all, if someone can just set a value, then how do you maintian your invariants (requirements of state)?

    If you have written a true operator that you have chosen to call "set", then your name is probably wrong at least.

    It's a distinction between grays in many cases.

    Rule of thumb: the code that changes a thing should be owned by the thing. If you are "borrowing out" some key value, operating on it in the wild, and then "putting it back in" you are probably making code that will cause you harm, because now everybody is "diddling" your state in their alien and undefined-to-you code.

    It's bad to be everybody else's (deleted).

    --
    Innocent people shouldn't be forced to pay for inferior software development.
    --"Code Complete" Microsoft Press
    1. Re:(not) Short Plain-English Version Answer by aCapitalist · · Score: 0

      Great post.

      You're spot-on when you say liberally exposing getters is not a bad thing, but be wary of too many setters.

      And I also think you made the point that if you're doing too much work outside of the class with getters and setters then it's time to step back and refactor that functionality into a proper method of the class.

  36. Re:Bring back procedural languages by tjstork · · Score: 1

    Yeah, this is a common pattern, and I've done it a lot myself, but do you see what you are really doing is just using your object hierarchy as -data-. If you put those relationships into a database of some sort, rather than in code, then adding a new thingy as you describe takes place in seconds and without a code redployment. Every good OOP design is just a bad use of a database.

    --
    This is my sig.
  37. OO Design Voodoo is a better name by MisterEntropy · · Score: 1

    The voodoo title would hightlight the real reason we need design patterns -- we (those of us in the software business) don't really know what we're doing. Just like witch doctors, we do stuff that satisfies some inner aesthetic, built up over the years through experience. We learn from our experiences, but don't really understand the causes and effects.

    1. Re:OO Design Voodoo is a better name by DevCybiko · · Score: 1

      speak for yourself. 'we' (apparently not you) know what we're doing. patterns condense best practices so that, basically, we have names for the things we all do over and over again.

  38. bn.com can't spell by larley · · Score: 1

    Holub on Patters: Learning design Patterns by Looking at Code Surprised nobody has mentioned this...

  39. want a review book instead? by Anonymous Coward · · Score: 0

    maybe you should grab a book about reviewing books instead

  40. In summary: by Sinner · · Score: 1
    Java sucks. To be specific, it sucks in "engineers" who use words like "business logic" and go on, and on, and on, and on, about "patterns".

    Basically "patterns" are a formalisation of "writing the same code over and over again". Probably all programmers end up repeating themselves from time to time, but if you do it so much that you need to formalise the process, then either you're severely lacking as a programmer, or your tools are severely lacking in reusability.

    I think the agglutination of people who talk about "patterns" around Java must necessarily indicate a fundamental problem with the language.

    It's worth thinking of a "pattern" as a kind of template class, and when you write code using that "pattern", you're instantiating that class, in your head. The amount of repetitive typing we do directly reflects how much our tools suck.

    To give a concrete example, I type a line like

    open(FILE, $file)
    || die "Can't open $file ($!)\n";
    in virtually every Perl program I write. This could be called an instantiation of the "robustly open a file pattern", if I was going to be a wanker about it.

    There are actually three different kinds of suckage going on here:

    1. Perl ignores the failure of open unless I tell it not to. But 9 times out of 10 I want that error check there. This is the suckage of inappropriate defaults.
    2. I could write a class to check the open by default, but then I'd need to install it everywhere my software runs. This is the suckage of software distribution.
    3. I could write a class to check the open by default, but then it would slow down every program I used it in. This is the suckage of manual optimisation.
    That last suckage is probably my biggest peeve with Perl. You can have fast code, or you can have good code, but you can't have both.

    I propose an antidote to all this talk of "patterns", for those of us who still believe that "business logic" is a dirty word. We should start talking about "suckage". In particular the suckage of writing the same damn thing over and over again.

    --
    fish and pipes
    1. Re:In summary: by Anonymous Coward · · Score: 0
      I could write a class to check the open by default, but then it would slow down every program I used it in.

      Trying to open a file usually involves going to the disk, which takes at least tens of milliseconds. Checking the status takes about 2 microseconds. So if your program does nothing except open files, the checks slow down your program by less than 0.2%.Why exactly do you think that is a problem?


    2. Re:In summary: by Sinner · · Score: 1
      Trying to open a file usually involves going to the disk, which takes at least tens of milliseconds.
      Actually, the vast majority of the time, the metadata will be in cache. Once in a blue moon I write something that scans the file system, or runs at startup, but those kinda things have other performance problems that concern me more.

      Also, when startup time is important, loading an extra module can make a big difference.

      Anyway, here's a benchmark. "direct" is my usual, hand-typed version. "wrapped" uses a nice wrapper. It is 16% slower. "ugly" is functionally the same as "wrapped", but is optimised for speed rather than readability. It is 9% slower than "direct". It appears that, on this machine at least, the overhead for reusable code is around 8 microseconds.

      Here is the raw results:

      Benchmark: timing 100000 iterations of direct, ugly, wrapped...
      direct: 7 wallclock secs ( 4.75 usr + 2.17 sys = 6.92 CPU) @ 14450.87/s (n=100000)
      ugly: 8 wallclock secs ( 4.76 usr + 2.78 sys = 7.54 CPU) @ 13262.60/s (n=100000)
      wrapped: 8 wallclock secs ( 5.87 usr + 2.19 sys = 8.06 CPU) @ 12406.95/s (n=100000)
      And here is the benchmark program itself:
      #!/usr/bin/perl -w

      use strict;

      use Benchmark;

      sub xopen {
      my($file) = @_;
      open(my $f, $file)
      || die "Couldn't open $file for reading ($!)\n";
      return $f;
      }

      sub xopen_ugly {
      open(my $f, $_[0])
      || die "Couldn't open $_[0] for reading ($!)\n";
      $f;
      }

      timethese(100000, {
      'direct' => sub { open(my $f, "/tmp/lemon.csv")
      || die "Couldn't open /tmp/lemon.csv for reading ($!)\n"; },
      'wrapped' => sub { my $f = xopen "/tmp/lemon.csv"; },
      'ugly' => sub { my $f = xopen_ugly "/tmp/lemon.csv"; },
      });
      Slashdot ate my indentation, sorry.
      --
      fish and pipes
  41. yhbt, yhl, ywnhand by Anonymous Coward · · Score: 0

    lol

  42. Re:Bring back procedural languages by roman_mir · · Score: 1

    No, the video properties are not database data, especially not the current value. Also the functionality of switching between the properties as well as functionality increasing/decrease the current property value has nothing to do with a database. You are confused.

  43. Ruby Needs Data Encapsulation Too by Bbazzarrakk · · Score: 2, Interesting

    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.

    This is totally off base. You're missing the point. This isn't about typing, it's about Data Encapsulation.

    Pop quiz, in Ruby no less. You have a class:

    class BankAccount
    attr_reader :balance
    def transfer_to(other_account)
    ...
    end
    end

    When your balance is off at the end of the day, you know where to look for errors. One of your methods, probably transfer_to(), is causing the problem. Change attr_reader to attr_accessor though, and then where do you check? Answer: The Whole Wide World! Good luck finding it, you'll need it.

  44. Re:goat.cx links above. by Anonymous Coward · · Score: 0

    lol, people like you are the reason why I keep trolling. you think I dont know that? the troll is in the fact that a whole bunch of you come in here to tell everyone the truth and then make a big rucas about it. its so LOL to watch 5 or 6 of you make a big fuss.

    I once wondered what the reason was.. thanks for the info.

  45. Re:Bring back procedural languages by tjstork · · Score: 1

    Actually it is a multilayered OOP design.

    From bottom to top:

    layer 0 is the server memory mapped file access layer
    layer 1 is the memory mapped block allocation layer
    layer 2 is the memory mapped skip list layer
    layer 3 is the profile engine layer
    layer 4 is the profile task layer. this is the vm implementation
    layer 5 is the socket listening layer and multithreaded job scheduler.

    then, on the client

    layer 6 is the socket layer
    layer 7 is the compiler parse thread
    layer 8 is the compiler tokenizer thread - yes, virginia, I put the tokenizer and lexer into separate threads on the client
    layer 9 is the data tier
    layer 10 is lightweight browsing / chart control tier - internally the new release of commodity server u/i has a mini browser. this is actually separated into two layers, the block rendering / page engine, and its window container. I also wrote my own chart control which has several views and really sweet date zooming.
    layer 11 is the user interface itself.

    It's a long time in the making and I'm pushing out the next big release soon. The reason for my memo was because during the course of the development of commodity server as well as a fairly big project at work, I've discovered that oop dogma for dogma's sake gets in the way. you have to keep in mind that oop was designed by the military and funded by big corporation as a way to get repeatable coding results out of idiots so that labor costs could be reduced and projects managed more smoothly and outsourced more easily. the emphasis of oop is not on individual productivity, but team productivity, and, as a lone developer, during the development of c/s, I've been gathering cons of oop languages towards the end of solo development. like, design a language that is good for a small team of no more than three or four people, and excels at individuals.

    --
    This is my sig.
  46. Re:Because OOP Has No Mathematical or Logical Basi by aCapitalist · · Score: 0

    Good post. I enjoy programming in something like C# not necessarily because of some dogmatic OO ideology, but mostly because of the libraries. In any case, the problem with bad OO is the deep hierarchies. Composition and programming to interfaces are favored over subclassing in modern OO thinking.

  47. Re:Bring back procedural languages by tjstork · · Score: 1

    Not confused at all. Table in your case could mean comma delimited file all the way up to some mini rdbms server.

    The properties are in a table. The table consists of these fields:

    property name, property type, property default value.

    The functionality of switching between properties is the selection of a row on table. This is in code. Also, the behavior of each of the property widgets is in code. In Windows you could, in C world, say that property type specifies the Window class.

    The user interface is initialized by loading data out of the table. Your message loop handles the obvious keystrokes.

    If you are smart, you could put the widget code in the property type table as well. But that would mean that your widget u/i layer would have to be in an interpreted language. Code is just a way of expressing a tree of execution, and there's no reason you can't map an OOP to a relational model, and the relational model is can be more flexible if implemented by the right software.

    --
    This is my sig.
  48. Need to understand motivating factors by tjstork · · Score: 1

    The problem that I have with OOP is that it is a religion to too many people that take each of its precepts as an excuse to not actually solve problems. I've seen a lot of developers balk at solving a problem, throwing out all of the precepts of OOP as complexities that make it harder to design. You hand someone a problem these days, and they will give you a beautiful class hierarchy of sorts that is beautifully polymorphic, data hidden, and doesn't do a damn thing that the customer wants and certainly took too long to do.

    Yet it's difficult to make a good OOP design, and oftentimes, many developers are just good enough to make OOP designs of very simple systems, but can't actually connect the dots and make complex systems using OOP because they simply cannot do the designs. And, ask most OOP activists about real language shortcomings, like, how most OOP languages are crippled for lack of dynamic dispatch, and they will just draw blanks or worse, roll out with a design pattern that is merely a workaround for a language failure. A solution yes, but an intellectual refusal to admit something could be better.

    We say OOP is good because it lets you implement good abstraction, but its become a cliche and I think that with all the CPU power we have, we might break up abstraction and reexamine the motivating problems that lead to its adoption, in light of modern hardware, widely available graph theory.

    Why, for example, do we have polymorphism? I say that it is a convenient way of arranging code in graphs to reduce decision logic. You factor if-then into class hierarchies? But why not other branching logic as well? And why just branching logic? Why not let one dimension hierarchies of code based on any common language construct!

    Why do we have strong data typing? Strong data typing makes for expensive designs and developers usually f--- this up. We have no automatic translation of types except by base class, or in some languages, by matching method syntax - C++ templates or C# generics. What if you could allow automatic conversions to take place? That's a run time check, but could you not avoid that by having iterate decision points in your code as part of a post-compilation but pre-execution step? It's just walking a tree.

    Why data hiding? We want to hide complexity, but then, we also don't. I had a C# problem the other day that could only be resolved, ironically, by looking at the mono source for the framework. So much for data hiding and black box code! Why not some way to filter chunks of code and or data streams on demand or at least in various cases.

    And finally, why are will still using imperative languages when everyone who ever fires up Excel to do a quick calculation rather than write a C# or Java program implicitly agrees that functional programs are easier to write!

    Admittedly, OOP, properly employed, will help us get to that "next step", whatever it is. That new language / paradigm will no doubt be implemented in an OOP language. But those people that think OOP is "the shit", well, I think they are just stupid.

    --
    This is my sig.
  49. Re:Bring back procedural languages by roman_mir · · Score: 1

    Yes, and your point is? All data ends up stored someway, in our case we used XML, whatever. The design of a property object has a loose corelation to the data model behind it. You can also say that everything is just bits. You can also say it's electrones' movement. What is your point?

  50. APPLAUSE!!! by Anonymous Coward · · Score: 0

    Porn on the first post! Bravo! This is indeed a pleasurable trend!

  51. Re:Bring back procedural languages by jonhaug · · Score: 1
    Well the reason the technique was originally invented was that the DOD was spending way too much money on software maintenance.

    What "technique"? The OO-technique? Well, then I am glad to inform you that it was not invented by the DOD. Simula was the first OO-language ever, and it was invented by researchers at NR.

  52. Java is used as the lowest common denominator. by Anonymous Coward · · Score: 0

    And therefore the title of the book is fine, although "Holub on OO design patterns" might be more accurate.

    As you pointed out, if you used a different language, for example one with multi-methods, then you could design things differently. However, there is some debate about whether these other languages are OO or not. For example, is the notion of "self" essential in an OO language? If so, multi-methods abandon the notion of self and cannot be classified as OO. What about method pointers? If "object-oriented" means that the objects are the first class citizens, then method pointers go against the OO principle.

    There is a lot of debate on these issues, and many people are not happy to call these features above as "OO". I think it is totally fine to use a language without these features as the tool to demonstrate design patterns in "pure" OO.

  53. real world not by Anonymous Coward · · Score: 1, Interesting

    I studied programming with Allen Holub, and can truly say I became a 'real programmer' under his tutelage. He's a literate and broadly intelligent man, and if I can boil what I got from him down to one sentence it would be: programming is writing. You know, like writing an essay or a novel. It should be clearly structured and readable by human beings.

    Beyond this, though, I think he's taken a bad turn. I haven't read the new book, but familiarity with any real-world programming is not Holub's strong suit. In fact, his dedication to strict OO procedures betray his lack of familiarity with the requirements of real jobs, where you're always forced, by changing requirements and time pressures, to make something of a mess.

    The 'game of life' example sounds typical: take a simple problem, implement a solution in a long-winded language (java), making the whole thing even more long-winded by adherence to preconceived pattern methodology, and you end up with a big enough mess for it to look like a 'real-world' program. But the situation is as artificial as any bubble sort assignment in a beginning programming class.Examples like this have zero relevance for what most programmers face when they are on the job: here, modify this million-line program which no-one really understands to fix this bug or add that feature.

    Let's realize what computer programming usually is: the creation, under great time pressure, of temporary solutions to problems which will go away or change soon. Worrying too much about purity of structure and reusability is not only unnecessary, it often paradoxically has the effect of creating programs too rigid to be modified over time as requirements change.

  54. Re:Bring back procedural languages by DrPizza · · Score: 1

    Except that increasingly people don't write IP stacks that way because it doesn't scale.

  55. More-OO-than-thou religious fanatics by Latent+Heat · · Score: 3, Insightful
    First it was this Law of Demeter business where you weren't supposed to invoke a method of an object you retrieved from another object and you were to either implement gobs of forwarding methods or implement "visitor" objects to do the forwarding or some such thing.

    Then there was the "inheritance is bad" deal where everything is to be done with composition and you have to write gobs of forwarding methods between the object and the object it contains.

    Now there is this "Get/Set is harmful" -- no, "Evil" I say because this is a matter of religion. So what are you supposed to do when you need to get some representation of state out of an object -- to display it? Can you do a getStateValue()? Oh, no! You have to hand that object an AWT graphics context object and have the object render itself. So much for reusing that object outside of Java.

    Or in another Golub article referenced on this topic, you are not supposed to have set functions to initialize an object to a required state -- you are supposed to pass your object a "Visitor" or "Strategy" object that supplies the state -- through what? An interface with a whole raft of get functions?

    Suppose the approach was, "Do you have a whole lot of get methods on an object? Why are they there? Is it because you need to retrieve the state of an object to print it out? Have you considered giving your object a Print() method and getting rid of all of the get methods? Are you concerned that your object is now hard-wired into a particular print driver? Have you considered implementing an abstract print interface and implementing void Print(IPrintInterface my_printer) as the Print method?"

    But no. The approach is that get/set is "evil" or "smells bad" or some such thing. An object with get/set is a kind of shame and you have to go to extreme contortions in your code, spinning off bunches of classes you never needed before to avoid the embarrassment of having get/set.

    1. Re:More-OO-than-thou religious fanatics by Anonymous Coward · · Score: 1, Funny

      You'd better quiet down or we'll have to send you to O-O Re-education Camp. You will be forced to sit around campfires and criticize the impure way in which you used to program.

  56. Re:Bring back procedural languages by tjstork · · Score: 1

    I guess I'm just going to have to write the language to show you.

    --
    This is my sig.
  57. Re:Bring back procedural languages by roman_mir · · Score: 1

    hahahahaha, you are a funny-man. Tell me a joke, man.

  58. Draw thyself?! by Anonymous+Brave+Guy · · Score: 2, Insightful
    So what are you supposed to do when you need to get some representation of state out of an object -- to display it? Can you do a getStateValue()? Oh, no! You have to hand that object an AWT graphics context object and have the object render itself.

    When I first read that, I assumed you were joking, and had just made that up as an absurd example to exaggerate the author's point. Then I read TFA, and realised that Holub himself advocated exactly that. Talk about getting your priorities completely wrong!

    Getters and setters are not "evil". They are a design choice, as Holub himself acknowledges. If you have a lot of these for a particular class, this is often symptomatic of a confused design, but the author missed the point here. The bits you're supposed to hide are the individual aspects of an object's state that must satisfy various invariant conditions. It doesn't make sense to change these independently, because you might violate that invariant. Hence, you only provide operations on the class that change them collectively such that they still satisfy the required invariant conditions.

    However, if something can be changed in isolation without violating any invariants, there's no harm in providing a mutator method to do it. That applies up to and including classes with no invariants ("structs") where you can sensibly modify any aspect of the state in isolation. Moreover, if some aspect of state has a meaning in isolation, there is no harm in providing an accessor method to look up that state, even if you wouldn't allow it to be changed directly because of invariant constraints.

    Confusing this with the idea that an object should be the only thing that can do anything with itself (such as drawing itself on a screen) demonstrates a spectacular failure to understand the underlying issues here. In fact, it's easy to show this: consider an operation where two or more user-defined types are involved, and you can't restrict all the knowledge about each object to that object and still perform the operation. Attempting to do so often results in exactly the problem with Holub's "draw thyself" example: it tightly binds two separate subsystems, forcing one class to live in both of them, with all the attendant spaghettiness that brings.

    Now, Holub clearly realises that mixing UI code with business logic has unfortunate problems. He can protest about inner classes and facade patterns all he likes, but the fundamental design concern -- coupling the UI system to a data-handling system -- is still there. The only way to break the bad coupling is to separate out the facade code or whatever from the original class, and put it in a UI-based layer where it belongs. Of course, that probably requires using some form of accessor methods, which takes up back to where we started.

    Who is this guy anyway, and why do some people here think he's good at this stuff? I honestly haven't heard of him before, and I'm fairly open-minded, but I'm not forming a good impression from reading a couple of his articles that people have cited in this thread.

    --
    If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
    1. Re:Draw thyself?! by alw53 · · Score: 1


      Clearly if the interface is more complicated than the implementation, it would be better to just expose the implementation. An object should expose the simplest interface that it can. To say that an object should hide its implementation, even if this makes the interface more complicated, is throwing out the baby with the cart before the horse.

    2. Re:Draw thyself?! by alw53 · · Score: 1

      In fact, I'll go a step farther and claim that the difficulty in modifying a system is linearly related to the total size of all of its public interfaces. This whole deal of hiding the implementation at any cost presumes that the implementation is complex and the interface can be made simple. If the class is just a bag of field values, the simplest and most transparent interface is to just make them all public.

  59. Everybody seems to be confusing everything :-( by Anonymous+Brave+Guy · · Score: 1

    The surprising thing here is that nobody seems to be considering that there are more than two concepts at work here: sure you've got the "total" and the "money to add", but you also have the operation of adding two monetary values together, and the operation of assigning that result to yield a new total.

    It doesn't matter whether you call the summation operation "+=" or "addTo" or "funkyTypeConvertingSummationAlgorithm". The operation is dependent on both the total and the amount, or more precisely on how their values are represented. There could be complications, perhaps due to type conversion issues: not just the obvious double vs. float type of thing, but for example the possibility that the amounts are value-currency pairs and exchange rates need to be considered.

    Until you've sorted out where responsibility for this sort of operation should lie within your design, messing around with whether the function that does it is a method of this class or that one (or a non-member function in a language that allows them) is running before you can walk.

    --
    If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
  60. Evidence for OO is plain Weak by Tablizer · · Score: 1

    Amen! The OO crowd is full of dogmatism but slight on evidence. The existing body of evidence that OOP is objectively better is slim or none[*]. That is the truth, whether you want to hear it or not.

    * Assuming we ignore anecdotal evidence. But, anecdotal evidence can be used to prove flying saucers are goosing humans in the dead of night.

    Rather than debate here, if you have solid OOP evidence, please place it here:

    http://www.c2.com/cgi/wiki?OoEmpiricalEvidence

    (I tentatively agree that OOP improves patterns that resemble device drivers, but that cannot be extrapolated into domains I am familar with.)

  61. Re:Bring back procedural languages by Tablizer · · Score: 1

    One common pattern with maintained code is the cancerous growth of special cases to deal with new requirements. Over time, the special cases dwarf the original code, and it becomes very hard to even figure out what it's supposed to be doing

    I agree that this is a huge problem. But OO does not seem to be the answer. Subtyping for specialization assumes a few things that don't pan out in reality.

    First is the granularity. Sometimes you need to override only 1/3 of an existing method. Either you have to make tiny methods up front (some propose this but I find it drandruff-like messy), or else reshuffle the code to get the newly needed granularity. If you have to reshuffle methods and classes, then it flunks the goal of being change-friendly.

    Second, if you study change patterns, you will see that the differences are not really tree-shaped. Inheritance usually assumes a tree-shaped change pattern. But, the real world has no Tree Cop that forces actual changes to be tree-shaped.

    Third, the differences often require different interfaces. OO is not designed to hide interface changes, only implementation changes.

    But then again, no paradigm that I have seen has easy solutions to this. The most promising ideas are based on set theory in my opinion, but it is too early to say whether they are the Golden Hammer for the messy Nails of Variation.

  62. Re:Bring back procedural languages by Tablizer · · Score: 1

    I have wasted countless days reading through nested if-then statements trying to figure out how something works.

    Is that the fault of the procedural paradigm or bad programmers?

    Sometimes there are ways to fix/simplify messy nested IF statements and sometimes there does not seem to be much that can be done. This appears to be because dispatching is based on multiple independent or semi-independent factors. It is essentially a multi-dimensional problem that we are trying to project onto a one-dimensional surface known as "text". OOP is not a fix because it's built-in dispatching is also only one-dimensional and multiple dimensional OO solutions, such as the Visitor Pattern, are at least as ugly as nested IF's, especially if we have more than 2 independent factors that are intertwining in our dispatching.