Announcement Announcement Module
Collapse
No announcement yet.
[lengthy Beginners Question] Dependency Injection, interfaces and implementations? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • [lengthy Beginners Question] Dependency Injection, interfaces and implementations?

    Hi all;

    just carefully taking my first steps in the Spring environment, so far I'm impressed by the functionality it provides, even though I don't have no idea so far how long it will take to at least slightly understand and get along with all that's possible in the Spring environment.

    At the moment, I am playing around a little, reading through tutorials and working through some examples, being left with my first question (of which I don't know whether it's a matter of missing understanding of how Spring works or some basic lack of Java knowledge):


    I am into building a very basic Notes implementation, currently using two interfaces:

    - "Note" as the interface to access a very note - getTitle(), getContent(), getDate() and the like,

    - "NotesList" as a List to keep track of notes - getNote(), addNote(), removeNote(), ...


    Each of those is currently implemented by a very basic class named "MemoryBasedNote" (basically an object storing properties in private variables) and "MemoryBasedNotesList" (the same - all notes stored in an ArrayList).

    A "NotesManager" class is supposed to handle this mess. This one has a setNotesList() function and recieves the MemoryBasedNotesList implementation via Dependency Injection. So far, so good.


    Now, I want to add a new note from within NotesManager. Usually, I'd do something like

    Note newNote = new Note(...);
    this.notesList.addNote(newNote);



    My problem, right now is: Using Spring and not wanting to hardcode any dependencies, I don't want to do

    MemoryBasedNote newNote = ...

    but want NotesManager to use an implementation of the Notes interface according to configuration. How to do that? Basically, how can I create a new instance while just knowing about an interface and not the very class to implement this? Can this be done using Dependency Injection (something like "setNotesImplementation()")? Is there a better way? Is this a stupid idea after all?

    Thanks for any hints (and for reading this far).
    Cheers,
    Kris

  • #2
    Originally posted by kawazu
    Hi all;

    just carefully taking my first steps in the Spring environment, so far I'm impressed by the functionality it provides, even though I don't have no idea so far how long it will take to at least slightly understand and get along with all that's possible in the Spring environment.
    If you understand the IOC-concept, you understand the fundamentals of Spring I think.


    but want NotesManager to use an implementation of the Notes interface according to configuration.
    You could create a NotesFactory:

    Code:
    interface NoteFactory{
      void create(....);
    }
    
    class MyNotesFactory implements NotesFactory{
        void create(...){return new MyNote(....)};
    }
    And you could inject the NoteFactory into the NoteManager.

    Code:
    class NoteManager{
       private NotesFactory notesFactory; //also setter for notesfactory
    
       public Note makeSomePrettyNote(String content, String title){
                 Note note = notesFactory.create(content,title);
                 ...store the notes in the db maybe
                 return note;
       }
    }

    Comment


    • #3
      Hi there,

      and at first thanks a lot for your hint. Much appreciated!


      Originally posted by Alarmnummer
      If you understand the IOC-concept, you understand the fundamentals of Spring I think.
      Oh, that's good to know. Actually, took some time getting used to it, but I guess once you got it, you don't want to work without it anymore...



      You could create a NotesFactory:

      Code:
      interface NoteFactory{
        void create(....);
      }
      
      class MyNotesFactory implements NotesFactory{
          void create(...){return new MyNote(....)};
      }

      Hmmm, that would be a solution, indeed. However, is this the "Spring" way to do so? I'm asking because, even though it is obvious and necessary, at this very point then I'm ending up having a dependency between the MyNotesFactory and the MyNotes class implementation which again is hard-coded... :o

      Thanks for your help and bye,
      Kris

      Comment


      • #4
        I think your example and terminology is a bit off.

        Note is a domain object. There are (normally) no interface/implementations for domain objects, they just are. They are not handled by Spring as they usually come from the database. (actually you get them through a DAO class, or you simply use new to create a new instance and later call something like dao.save(mynewinstance)).

        Your NotesList class is actually a DAO class, and MemoryBasedNotesList is a memory managed implementation of it.

        Now that terminology is more clear you can take a look at Spring examples to see how DAOs are handled in Spring and how domain objects are managed.

        Comment


        • #5
          Originally posted by kawazu
          Hi there,
          Hmmm, that would be a solution, indeed. However, is this the "Spring" way to do so?
          There are different solutions (Spring is very powerfull) and you can seriously make your objects very difficult to understand. But I like a good design and Spring doesn't mean you should throw good design overboard.

          I'm asking because, even though it is obvious and necessary, at this very point then I'm ending up having a dependency between the MyNotesFactory and the MyNotes class implementation which again is hard-coded... :o
          It is hardcoded, but the goal of the MyNotesFactory is to create specific instances of MyNotes. If you create a CoolNotes, you also need to create a CoolNotesFactory. This isn't bad programming

          Comment


          • #6
            Originally posted by dejanp
            I think your example and terminology is a bit off.

            Note is a domain object. There are (normally) no interface/implementations for domain objects, they just are. They are not handled by Spring as they usually come from the database. (actually you get them through a DAO class, or you simply use new to create a new instance and later call something like dao.save(mynewinstance)).
            With Anemic Domain Models you don't create interfaces, but if you have rich Domain Models, I think interfaces will be usefull.

            Comment


            • #7
              Originally posted by kawazu
              Oh, that's good to know. Actually, took some time getting used to it, but I guess once you got it, you don't want to work without it anymore...
              http://www.martinfowler.com/articles/injection.html

              Comment


              • #8
                Folks,

                first off, thanks a lot for your hints and inspirations - much appreciated as it makes one always look into something new (Anemic Domain Model...).

                Anyhow, I've been meditating on all of your advices and found some answers making me think again:

                - Basically, the Factory approach seems to be the most familiar one to me. I'm still in the process of finding out where "loose coupling" works and where things just need to be coupled a little tighter. Talking about a factory to return an instance of a specific implementation class, a tighter coupling seems to be implicit?

                - For what I've seen so far, using a DAO in order to persist the "domain" objects (notes, in my situation) would be the way to go anyhow. I read a bunch of tutorials and examples on how to deal with DOAs, and the way they are used for retrieving and storing new objects seems to be logical. However, when creating new domain objects, at some point of the examples there's always a " = new BusinessObject(...)" - is it right to assume that, this way, business objects are treated as classes which are implemented "as is" and, then, just around for everyone to use no matter where? Doesn't that mean breaching the idea of Dependency Injection?

                Sorry if repeating things already known or discussed, but right now I am striving to understand...
                Thanks and bye,
                Kris

                Comment


                • #9
                  I don't think DI is a purist "all or nothing" pattern, and using a pattern where and when it makes sense is the most important of all patterns.

                  Anyway, DI is a pattern (theoretically) independent of the instantiation strategy. Instantiation depends on language features - in C++ you could theoretically override new operator to do whatever you want, including DI, and in java you could use AspectJ do achieve the same (supported by Spring 2). Also, instantiation in your own code is normally the least of your worries - real problem are the instances created by your ORM.

                  In praxis you want to use DI to build your application infrastructure - 99% of the stuff you want to inject somewhere are infrastructure service singletons, and they are being injected in other singletons, and I'd suggest you concentrate on that part, leaving domain objects out of the picture for now. Later, if you find out you really need to inject something into them, it will be technically possible (see AspectJ support).

                  Comment

                  Working...
                  X