• Frister (unregistered)

    What the frist! That is exactly what I was doing (i.e. told to do) at my frist dev job!

  • (nodebb)

    This is how most "what's the best way to" kind of questions end up.

  • Hans (unregistered)

    Creational patterns - a reason to get creative!

  • (nodebb)

    There are two separate WTFs today: one from the "Emiko" and one from Remy, who for some unfathomable reason still peddle this nonsense about Spring and patterns. SimpleBeanFactoryAwareAspectInstanceFactory and other classes with word-salad names have absolutely nothing to do with patterns (GoF or otherwise); they just form a quite complex and very hacky way to work around basic Java deficiencies, namely the utter lack of metaprogramming. Which is actually the very reason of Spring existence.

  • Brian (unregistered)

    Oh, IoC... I got a brief taste of that at my previous job, and then got shoved headlong into it with my current one. I get its merits, but whoever designed our codebase went way overboard - every class (other than pure data ones) has an interface, and every interface is registered in the thousands-of-lines-long registration method. And then we get the God-classes that have constructors with 20-something injected parameters, half of which are assigned to otherwise unused member variables, and other classes whose constructors mix IoC and non-IoC parameters together (these are usually base classes, but not always).

    The only positive thing I can say about it is that it does make unit testing easier, at the cost of adding code bloat and sacrificing some compile-time error checking.

  • pudin9 (unregistered)

    WTF I thought you were kidding with SimpleBeanFactoryAwareAspectInstanceFactory but I looked it up.

  • Tom (unregistered) in reply to Brian

    Not sure what language you're using, but in general, using a DI Container and then manually registering your classes is pointless - Mark Seemann put it in a lovely graph on his blog: https://blog.ploeh.dk/2012/11/06/WhentouseaDIContainer/

  • (nodebb)

    If "MessageCType" is something that has a probability of EVER needing to be mocked/substitued/replaced, then this is actually a good pattern... Consider a code bas with 10,000 lexical variations of "new MessageCType(...)"... then having to do a replacement. Having a minimal method such as the one shown will allow for many capabilities, including, buyt not limited to handling the above...

  • (nodebb)

    Java: The verbosity of Cobol - now with objects!

  • Naomi (unregistered) in reply to TheCPUWizard

    If "MessageCType" is something that has a probability of EVER needing to be mocked/substitued/replaced, then this is actually a good pattern... Consider a code bas with 10,000 lexical variations of "new MessageCType(...)"... then having to do a replacement. Having a minimal method such as the one shown will allow for many capabilities, including, buyt not limited to handling the above...

    That really depends on the class contract as it relates to those specific properties. As it stands, this implementation actually misses all the advantages of a factory method. On the one hand, it violates compile-time type safety (I'm going out on a limb here and assuming that a message has at least one required field - either body or type seem like they could be required.). On the other hand, because it doesn't take any parameters, it can't make any intelligent decisions about the initialization process. And while this isn't really a problem with the factory method itself, the fact that MessageCType directly exposes its fields makes it damn near impossible to change the implementation, too.

    I'm going to switch to geometry to provide a counterexample:

    public interface Vector2 {
    
        double magnitude();
    
        double direction();
    
        Vector2 normalize();
    
        Vector2 add(Vector2 other);
    
        static Vector2 of(double magnitude, double direction) {
            if (magnitude == 0) {
                throw new IllegalArgumentException("degenerate vector");
            } else {
                return new VectorImpl(magnitude, direction);
            }
        }
    
    }
    

    (continued)

  • Naomi (unregistered)

    But perhaps it turns out that your application spends a lot of time normalizing vectors that have already been normalized. Well, we've got a really simple fix for that!

    public interface Vector2 {
    
        double magnitude();
    
        double direction();
    
        Vector2 normalize();
    
        Vector2 add(Vector2 other);
    
        static Vector2 of(double magnitude, double direction) {
            if (magnitude == 0.0) {
                throw new IllegalArgumentException("degenerate vector");
            } else if (magnitude == 1.0) {
                return new UnitVector(direction);
            } else {
                return new VectorImpl(magnitude, direction);
            }
        }
    
    }
    

    One change, one place, and we've just eliminated the performance problem (and you could imagine something very similar coming up to support a refactoring), and we're still safe against degenerate inputs. This nullary factory provides neither benefit.

    About the only thing this approach could offer is some sort of object pooling... which is actually considered an anti-pattern (in Java) because the JVM's garbage collector is just that good. (Yes, there are exceptions to every rule, but this isn't a thread pool and it's... presumably not using any external resources.) In other words, it's no better than a naked constructor call, and the only thing you've done is exchanged "ugh, I have to change all these constructor calls" for "ugh, the thing broke because someone forgot to set a field properly", and frankly, the latter is worse.

    Don't do this.

    P.S. If you need to create test mocks, that's what Mockito is for.

  • Naomi (unregistered) in reply to slapout1

    (Because of course half my message gets held for moderation...)

    Java: The verbosity of Cobol - now with objects!

    That really isn't fair - these ReallyVerboseAbstractBeanFrobnicationStrategyPatternDuckConjugatorWidgets are deep in framework code. If you have to routinely interact with them, then either you're working on a framework or something has gone very wrong. They're fun to joke about, but as a serious complaint... it frankly gives the impression the complainer hasn't worked with the language much.

  • (nodebb) in reply to Naomi

    P.S. If you need to create test mocks, that's what Mockito is for.

    Wow. Not "Mockhiato"?

  • (nodebb)

    Hmm, if it makes little difference in performance, I wonder if somebody is getting paid by lines of code.

  • Officer Johnny Holzkopf (unregistered) in reply to slapout1

    Whatever your choice of "enterprise language" is, you'll find interesting long names: System.Windows.Forms.IDataGridColumnStyleEditingNotificationService, org.apache.xmlrpc.server.RequestProcessorFactoryFactory.RequestSpecificProcessorFactoryFactory, InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState, SpinnerSpinnerFormattedTextFieldPainter, DeleteContentTypeXmlDocumentResponseDeleteContentTypeXmlDocumentResult, CNLabelContactRelationYoungerCousinMothersSiblingsDaughterOrFathersSistersDaughter . . . due to a lack of preview, let's hope all the greatness of those names will be preserved for the interested audience.

  • (nodebb) in reply to Brian

    every class (other than pure data ones) has an interface, and every interface is registered in the thousands-of-lines-long registration method

    There are cases where having an interface for every service class makes sense (such as if you're working in OSGi, where the framework synthesises a lot of classes for you so that you can do dynamic code replacement; simultaneously amazing and terrifying) but a lot of programmers seem to have no idea why anyone would do this — after all, their knowledge of the language is about as deep as a small puddle — and so end up cargo-culting that sort of thing everywhere.

  • Erin (unregistered)

    The problem with constructors isn't that they directly construct objects. The problem is that they're effectively a static method call, and static calls are notoriously difficult to properly test. Wrapping a constructor in another static function without any other purpose is entirely pointless and confusing.

    Java's "of" pattern is a bit of a special case because it does do something else even if it doesn't look like it at first glance - it works around some of the restrictions of the Java generics system and the issues with type erasure. It's not done purely to avoid having constructors, as the article's example seems to be.

Leave a comment on “On the Creation”

Log In or post as a guest

Replying to comment #:

« Return to Article