Announcement Announcement Module
Collapse
No announcement yet.
Spring != OO support ... Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    Use factories

    Originally posted by jladd
    All,

    Yes I did make some strong statements and that was intentional.
    Mostly so that I could get strong answers and I have.

    My first venture into spring wasnt by choice and the examples that were used and approach that was promoted required get/set for everything which made me cringe. yatesco - Pointed out that you could use constructors and I knew this and I was hoping that in the later versions of spring or somewhere in the doco there was something that said the constructor approach was preferred over get/set. I dont like get/set because it exposes the implementation of an object and doesnt help in keeping objects immutable.

    yatesco whose replies I appreciate says that I should be using interfaces and I do and that the methods of the interface will be public and yes they are, as they can't be any other way.

    My question is, does the class that implements the interface have to be public as well ? Id prefer to have its scope package only so they can not be created outside the package except by a 'factory'. Otherwise people might construct them themselves directly.

    Please dont get me wrong, I think Spring is a great framework and its come a long way and has a lot of takeup. Maybe my question should be "is there a set of best practice guidelines for using spring ?" ie: spring 'can' be used in a very OO way, but what does it do to 'enforce' this ?

    Thanks again for the replies.

    Rgs, James.
    You can still have a class with package level access and create a factory to inject it into other classes.
    There are numerous factory classes that you can use, especially look into API for MethodInvokingFactoryBean
    http://static.springframework.org/sp...api/index.html

    I really don't see which part of OO principle does Spring violate...
    Setters are infact very useful because they enforce the design requirements of the class. One of the best books i have read was Object-Design..by Rebecca, it clearly states that it's an object responsibility to document its requried collaborators, role(s), responsibilities, and after-effects of using it...
    So setters really give an idea about the object's collaborator's and doesn't disclose what the object is really doing... though they recommend that objects should be able to perform their responsibilities with less dependency..

    Anyway, what i am trying to say here is setters aren't really bad, it all depends upon how design it. If you have more than 6 setters that means your object dependency on others is really high...

    Regarding immutability, it applies more to domain objects than service objects. Service objects are really neutral and perform actions on the domain objects.. Service objects collaborate with other objects to achieve a certain goal [like use-case scenario etc]....
    Domain objects should be the one to enforce immutability depending upon the state they are in...
    I am using combination of AOP and factory classes to really hide the implementation...[but i made sure i have good documenation for it]

    Comment


    • #17
      More great responses ...

      Thanks Everyone,

      I knew there would be a way to ensure that Spring could be used in an OO way. I was very interested in bringing this out and hence the rather 'bold' statement.

      I will use all the excellent responses to shape an OO use of Spring

      Thanks.

      Im still keen to see responses even though I am sold
      and Spring == OO

      Rgs, James.

      Comment


      • #18
        Originally posted by cepage
        There are a lot of smart people who get concerned about the mutators, and I'd love to have a better understanding why.

        With good OO design, you should be accessing classes through their interfaces, and not through their concrete implementations, and Spring does a great job of helping you to implement your applications this way.

        For injected dependencies, I don't put mutators in the public interface. Period. Yes, there is a public setter method, but if your code is accessing the bean through its interface, then for all practical purposes it is private.

        Sure, Spring doesn't 'enforce' private access to the mutator, but the only way you could get to it is by directly invoking the class's concrete constructor (or casting to a concrete class), and that's a no-no.

        If you can't get your team to reference classes through injected interfaces, rather than invoking concrete constructors, then you aren't going to be able to 'enforce' OO principles anyway, and Spring can't do anything about that.
        Good point.
        I don't think the access level quesiton applies directly to spring but to design in general.

        In terms of the instantiation question of setter injection vs constructor i do think this is a valid issue. When I started learning spring i spent a significant amount of time reading on it and this was one of the things that stuck out in my mind. Why on earth would people use setter injection to initialize dependencies when that doesn't enforce a clear contract of the dependencies?
        Instead the user is responsible for making sure they are fully aware of the class api and what required dependencies are. But as I read i noticed most of the big sping advocates also seem to choose initialization through setters as a best practice. So, i tried both techniques thoroughly and my conclusion is that initialization through setter injection is just more natural when working with spring Ioc both from the actual configuration files to the idea of it. I don't think it is any more than that. Sometimes setter injection is nice to avoid constructors with way too many parameters. I also know people suggest it being usefull when working with interfaces that define dependencies using setters, but i don't think interfaces should define dependencies in most normal cases anyways.

        As someone else pointed out, one great thing about spring is that it gives you choices. When I started using spring at first i was trying to pin point best practices and didn't really make much progress. So instead I just started using it and on issues like this where you just aren't sure of a best practice, try both options spring offers in your application and you will soon figure out what you like best and maybe how certain techniques can be used better in different cases.

        Comment


        • #19
          Originally posted by wexwarez
          So, i tried both techniques thoroughly and my conclusion is that initialization through setter injection is just more natural when working with spring Ioc both from the actual configuration files to the idea of it. I don't think it is any more than that.
          Why are setters more natural? You can autowire by name with setters (and not constructors) but IIRC you can autowire constructors by type....

          Originally posted by wexwarez
          Sometimes setter injection is nice to avoid constructors with way too many parameters.
          I would suggest this is probably a code smell anyway If you have two many collaborators it *probably* implies that your class is doing too much....

          I think this is a really interesting thread, and just wanted to understand your POV a bit more

          Comment


          • #20
            Originally posted by yatesco
            Why are setters more natural? You can autowire by name with setters (and not constructors) but IIRC you can autowire constructors by type....
            Setter Injection can actually be used in most application situations. Autowiring by type falls apart as soon as you have two dependencies that implement the same interface. Constructor injection is out when you want to wire an object (Webwork Action, Hibernate-persisted object) that is instantiated by a third party.

            But I take the point about constructors offering a more explicit component contract.

            Comment


            • #21
              Originally posted by cepage
              Setter Injection can actually be used in most application situations. Autowiring by type falls apart as soon as you have two dependencies that implement the same interface. Constructor injection is out when you want to wire an object (Webwork Action, Hibernate-persisted object) that is instantiated by a third party.
              Sure, but these are all "convenience", not intuitive (as "natural" implies) considerations. I wondered whether the OP was implying that setters are more "natural" from an OO POV.

              Comment


              • #22
                Originally posted by yatesco
                Why are setters more natural? You can autowire by name with setters (and not constructors) but IIRC you can autowire constructors by type....
                I will try to explain my point of view. From what I can tell spring is built around using javabean style accessors, i think this shows in the configuration options. I think setter injection is easier, and more consistent to work with in the configuration file unless working on the simplest couple argument constructors. Even just the fact that you get to use the name of the propery in setter injection is a big bonus in the configuration. I understand that consturctor injection is limited in this way because the names can't be attained through reflection but nevertheless this ease and consistency of configuration is one of the big reasons it feels more "natural" to me.

                On this same kind of feeling, spring was built for flexibility and i get the feeling one of the reasons setter injection is embraced by it's senior users is that it also provides the most flexibility. Like setter injection allows you to work with mutable depenencies, it is more friendly for situations with defaults and pretty much anything that isn't the norm.

                I don't think it is so much that it adds value from a design standpoint but more from a development standpoint. In my mind the idea that constructor injection allows you to enforce this explicit contract with the required collaborators trumps all these points. But honestly being able to write the configuration with the simplist xml possible and the fact that when I glance back at my configuration files I am able see the names of the properties i am setting makes life easier from a development and maintenance standpoint and that is the crux of why setter injection just feels easier and more natural to use with spring for me.

                Comment


                • #23
                  Nice explanation wexwarez.

                  FWIW I tend to live in between setters and constructors I tend to document mandatory collaborators as constructors, but optional parameters/collaborators as setters. If it is feasible, I tend to set mandatory collaborators with defaults in constructors, but I provide overloaded ones. This does get tiresome and confusing very quickly

                  It is a shame that you cannot name constructor arguments Or at least retrieve them from reflection.

                  Nice post.

                  Comment


                  • #24
                    Originally posted by yatesco
                    It is a shame that you cannot name constructor arguments Or at least retrieve them from reflection.
                    I remember reading it somewhere that Mustang is supposed to support runtime parameter name reflection. Not sure whether it got dropped somewhere along the line.

                    Comment


                    • #25
                      hmmmn,

                      Ok, are we talking about public setters for injection or a lesser scope (protected/private) ?

                      Couldnt you use the factory approach (earlier in thread) to help in situations where the constructors may be a bit messy ?

                      Another question I have is what are the pro's and con's of making the
                      entire use of Spring invisible to the caller code? For example:
                      I see code that uses the application context to get object via Spring, but to me this make visibile the implementation details. Shouldnt such a thing be hidden inside a factory ?

                      Im also interested in how operations are composed using Spring.
                      I try to always think in terms of asking the object with the information to do the things I need, rather than asking it for the information and doing the work myself. Therefore, this would lead to asking an object to store itself and it handling the interaction with other objects to do so. How do other compose operations when using Spring?

                      How would people handle a situation like this:

                      SomeObject someObjectInstance.storeOn(someMedia);

                      Where someMedia could be a database or just as easily a flat file or some
                      destination ?

                      Rgs, James.

                      Comment


                      • #26
                        I see code that uses the application context to get object via Spring, but to me this make visibile the implementation details. Shouldnt such a thing be hidden inside a factory ?
                        Yes, as usual there's a way to do this. Check out ObjectFactoryCreatingFactoryBean. There are various other ways too depending on whether you want to use prototypes or singletons.

                        How would people handle a situation like this:

                        SomeObject someObjectInstance.storeOn(someMedia);

                        Where someMedia could be a database or just as easily a flat file or some
                        destination ?
                        Probably wouldn't. I think the whole Domain Driven Design thing is a bit overrated without actually buying you much. You're never going to get some magical object to travel over the wire, to the (web) user interface, back to the server and then ask it to store itself -- without wrapping it in various application layers with the extra needed and relevant functionality. So i'd do it like this:

                        Code:
                        someMedia.store(someObjectInstance);
                        where someMedia is something like:

                        Code:
                        public interface Media {
                        
                            void store(Object obj);
                        }
                        This is remarkably similar to how Hibernate works now.

                        For my 2c, it's much better to have the least amount of clutter possible, and so dealing with a pure data 'struct' object in the web layer is better. I don't want to see any 'store' method when i'm about to send something across the wire, or render a JSP page.

                        Others will disagree. I think the longest post on this forum is in fact about domain driven design and how it could be applied to Spring.

                        The closest I ever saw to someone putting everything plus the kitchen sink into an object in the name of "proper OO design", was an agent-based toolkit several years ago called Voyager.

                        It would have done it like this, which is closer to answering your original question.

                        Code:
                            someMedia.persistenceOf().store();
                        This approach meant that not everything was *directly* exposed and instantiated in the object, but you could obtain some aspect of an object fairly easily if needed.

                        I'd be quite interested to hear feedback from people investigating Domain Driven Design in Spring as to whether this old Voyager approach has any merit in a Spring world.

                        Comment


                        • #27
                          Interesting ....

                          I think your reply is interesting because I can be happy doing this:

                          someObject.storeOn(someMedia) {
                          someMedia.store(this);
                          }

                          and this is almost equivilant to what your suggesting.

                          So is the issue here if the method is in the object or outside?

                          If you just had someObject and it didnt provide a "storeOn()" how would
                          you tell it could be persisted ?

                          Rgs, James.

                          Comment


                          • #28
                            Originally posted by jladd
                            I think your reply is interesting because I can be happy doing this:

                            someObject.storeOn(someMedia) {
                            someMedia.store(this);
                            }

                            and this is almost equivilant to what your suggesting.

                            So is the issue here if the method is in the object or outside?
                            I think it is to do with responsibilities. Sometimes, whilst trying to avoid the anemic model it is too easy to go to a fat model (excuse the terrible analogy ).

                            Quite simply, is it a responsibility of someObject to be stored, or is it the responsibility of someMedia to store someObjects?

                            The good old example I always use is bank accounts, should a bankAccount be created (account.create()), or should a Bank create an account (Bank.create(account)).

                            I personally think account.create, or someObject.storeOn() is a leakage of concerns. An object should do *one thing*, but do it very, very well

                            Just my 2 pence.

                            Comment


                            • #29
                              anthropomorphic ....

                              yatesco i really like your replies.

                              I think that if you are anthropomorphic with your objects which I think you should be as they are meant to model the world then you find a more natural place and order for methods.

                              In the account example you give, when you needed an account where did you go ? The Bank, so therefore Bank.create() makes more sense.
                              When you transfer money who do you ask ?

                              I think that someObject.storeOn(someMedia) isnt a leakage of concerns because someObject has the information and we are asking it to do the work. The fact that it delegates to some other object or more correctly 'should' delegate to some other object doesnt mean the object is no longer doing one thing well. someObject is just being someObject and since someObjects can be stored its doing that well.

                              Consider a Book and a Library.
                              If you ask the Library to put the Book on a shelf then the library must ask the book which category its in. Doing so means some sort of 'get' from the book. However, if you ask the Book to return to a shelf in the library 'book.returnToShelfIn(library)' then book which has the information about its category can ask the library to do the work: library.putBookInCategory(book, category)'
                              This approach decouples the book and the library. If you asked the library to put the book on a shelf without the category then it has no choice but to ask the book for the category. This 'asking' will bind it to the book and possibly the type of category object returned.

                              I think this is a subtly thing and well worth considering as its like an inversion of control for the approach taken on where methods are, much like Spring and IOC for dependant objects.

                              Rgs, James.

                              Comment


                              • #30
                                Originally posted by jladd
                                Consider a Book and a Library.
                                If you ask the Library to put the Book on a shelf then the library must ask the book which category its in. Doing so means some sort of 'get' from the book. However, if you ask the Book to return to a shelf in the library 'book.returnToShelfIn(library)' then book which has the information about its category can ask the library to do the work: library.putBookInCategory(book, category)'
                                This approach decouples the book and the library. If you asked the library to put the book on a shelf without the category then it has no choice but to ask the book for the category. This 'asking' will bind it to the book and possibly the type of category object returned.
                                I take your point, but I think you have chosen a bad example

                                The category that a book is in is an attribute of the relationship between a book *and* the library. If your book is truly modelling the book, then that same book may belong to different libraries, each with different categories

                                You might have a Library, a book, and a LibraryBook.... libraryBook.return and libraryBook.takeOut would make absolute sense (to me)

                                If you only have a Library and a Book then I still think the categorisation of that bookin is the responsibility of the library.... Would I code a book.return()? Maybe. Could domain gurus spend hours and hours discussing where the return method belongs; almost certainly

                                Comment

                                Working...
                                X