Persistent Domain Objects Pattern.

Discussions

J2EE patterns: Persistent Domain Objects Pattern.

  1. Persistent Domain Objects Pattern. (13 messages)

    Abstract

    Persisting domain objects is one of the most challenging aspects of designing a flexible and testable enterprise application. There are lots of examples, in the industry, when developers get it wrong and end-up either with an effectively procedural, non-object-oriented structure and/or a highly complicated, tightly coupled design which is hard to unit-test.

    Persistent Domain Objects Pattern gives a solution to tight-coupling of the persistence and application logic code. PDO decouples those by extracting the details of the persistence implementation and hiding it behind an interface, employing Dependency Injection techniques. As a result, domain objects do not need to know or worry about the details of the persistence code and can concentrate on their main task - delivering encapsulated data and behavior that models the domain under question. It, also, makes domain objects, much easier to unit-test in isolation from its dependency - persistent storage (e.g. database). Effective unit-testing increases the quality of a programming code and its extensibility.

    Scope

    Domain Model, Persisting Domain Objects.

    Problem Definition

    The core of most applications is their Domain Model. A Domain Model defines business rules (behavior) and the data that the business rules apply to. The behavior and the data are encapsulated into objects that form a hierarchy and can interact with each-other, thus effectively modeling the domain reality. For a wide-range of applications this Object-Oriented way of modeling the real-life scenarios works with the best, most effective approximation possible.

    Usually, humans desire to interact with the model, in one way or another: influence the system or get a glimpse of what is going on. This is achieved via a View layer. Since the business rules (Model) change far less frequently than the user interface to the system (View), there is, often, a requirement of being able to change View without disturbing the Model. The requirement can be satisfied by decoupling Model and View through the introduction of a Controller. This brings us to the infamous Model-View-Controller (MVC) pattern.

    If we could just start-up an application in-memory and guarantee that it always stays there, the above would be as much as we would have to worry about. Alas, that's not the case. We have to periodically (or constantly) backup a snapshot of the system's state into some kind of persistent storage. This way we can restore the state from the backup, if needed, or share it with others. The motivation and mechanisms, for the persistence, can be numerous and different but it is, almost, always necessary.

    In fact, the persistence is so important that some people begin with the design of the persistent storage (e.g. DB tables) and end-up with a so-called Anemic Domain Model and a separate "Service Layer" consisting of queries to the persistent storage. Martin Fowler et al. have identified it as an anti-pattern. Such tight coupling of the application code and the persistence one, makes it very hard to unit-test your application - makes application code less reliable and extensible.

    Solution

    One solution to the defined problem is to abstractly extract the concrete implementation of the persistence code out of the Domain Model. Basically: decouple the persistence from the application code. By decoupling, besides making our application much easier to unit-test, we will, also, make it more flexible - different persistent storage mechanisms (LDAP, DB, plain files, XML etc.) can be swapped-in on-demand, without affecting the application code and logic.

    While we do this, we have a supplemental goal: we want to keep the implementation simple. One way of achieving the goal is to declare persistence as a dependency of a domain object. We can introduce a Manager interface that our domain object depends on for all its persistence needs.

    Concrete implementations of Manager can be registered with the appropriate entities using Dependency Injection; so that the entity itself never needs to know the specific implementation used.

    Sample Code

    In this sample, we will look at a Blog entity. For the purpose of this demo, we will use the Context IoC introduced by Sony Matthew. The reason why we choose it over the Constructor or Setter Dependency Injection is to make example code simpler.

    Let's look at the Blog interface. Please, note that the only addition to the interface, that would not be present in a "pure" domain object, is the declaration of the interface for the persistence dependency:

    public interface Blog {

        public interface Manager {
            //-- The argument to the load() method is entity's PK
            public Blog load( String name );
            public void save( Blog blog );
            public void remove( Blog blog);
        }

        //-- The rest of the interface goes below
        // .....
    }

    Implementation:

    public class BlogImpl implements Blog {

        private static Blog.Manager manager = null;
        public static Blog.Manager getManager () {
            return BlogImpl.manager;
        }
        public static void setManager ( Blog.Manager manager ) {
            BlogImpl.manager = manager;
        }

        public BlogImpl() {}

        private String name = null;
        public String getName() {
            return this.name;
        }
        public void setName( String name ) {
            this.name = name;
        }

        //-- Below go any other properties and methods relevant
        //-- to the Blog entity as a purely Domain Object.
        //.....
    }

    In the above example, the primary key of the Blog entity is the name property.

    One of the manager implementations may look like the following:

    public class BlogManagerImpl implements Blog.Manager {

        public BlogManagerImpl() {}

        public void save( Blog blog) {
            //-- Save the state of the Blog object, into a database
        }

        public Blog load( String name) {
            //-- Load the Blog instance from a database.
            //-- e.g. using hibernate:
            //-- return (BlogImpl) session.load( BlogImpl.class, name );
            
            //-- this is just for the demonstration purposes
            BlogImpl blog = new BlogImpl();
            blog.setName ( name );
            
            System.out.println ( "Loaded blog: " + blog.getName() );
            return blog;
        }

        public void remove( Blog blog) {
            //-- Remove the persisted state of the object from the
            //-- database..
        }

    }

    and, finally, the following is how your application may use all of the above to load two blogs:

    public class Main {
        public static void main(String[] args) {

            BlogImpl blog, blog2;
            
            Blog.Manager blogManager = new BlogManagerImpl();;
            BlogImpl.setManager( blogManager );
            
            blog = (BlogImpl) BlogImpl.getManager().load ( "John" );
            blog2 = (BlogImpl) BlogImpl.getManager().load ( "Joanna" );
        }
    }

    each call to the getManager().load() will load an entity from a database. For the purposes of this demo, it, also, displays a message.

    Conclusion

    Using the PDO pattern, we have extracted the persistence code details out of the Blog entity. This made Blog entity more object-oriented. By decoupling its dependency (a database, in this case) from the entity, we made unit-testing the entity much easier. Better unit-testing delivers more reliable, extensible code and significantly improves the overall design.

    Threaded Messages (13)

  2. I like the idea of having a rich domain modell which is build on POJOs offering business logic on the right place.
    Given this makes it very easy to test our business objects respectively business logic without any dependency of the environment, e.g. container.

    Moving persistence out of the service layer and having rich business objects is therefor an excellent step in the right direction.

    I also appreciate the idea of separating concerns, thus the separation of business logic and persistence is a very good consideration. I wonder if we could achive this, if we treat persistence as an 'aspect' without bothering our business objects with this issue.
    According to this, our business objects wouldnt have any code thats looks like handling persistence, even it's a simple delegation to an abstract PersistenceManager - it should'nt be aware of beeing persistent.

    So how could we achieve persistence where this responsibility belongs neither to a service layer nor to the plain business object?
    The answer could be, that persistence is treatet as an 'aspect' with which our business logic is adviced. Getting some usefull hints from the spring framework, we could solve this by having a PersistenceDecorator, which decorates our business object and adds the needed persistence functionality (like spring we could use an DynamicProxy which takes the burden of fullfilling the whole interface of our business logik).
    This might be a drawback - we need an interface for our business object in order to use a decorator, but using interfaces rather then class-implemantations is'nt just a bad pattern ;o).

    An advantage is surely an even simpler way of testing, yet you does'nt have to supply a mock (of your Persistence Manager) to your business object for testing your business logik - you've just separated that aspect ;o)

    What's your opinion about that? Any notions are appreciated.

    Best regards

    Mario
  3. Mario,

    thank you very much for your comment.

    I absolutely agree with you. In the initial version of the pattern - we achieved to separate persistence from the domain objects, but there are, still, some leftovers, as you noted: domain object needs to have setters for a manager. It does not need to know the exact _implementation_ of the manager, which is the primary goal, but it has some extra lines of code, indeed.

    Also, some higher-level object (in this case: main method) needs to assemble the domain-manager relationships.

    Yes, with proper AOP advices introduced we could further clean-up the code. But that will slightly complicate the picture so, for the demonstration's sake, I preferred to show a much simpler solution. Also, pattern is an abstract description and introducing AOP's and Java way of advising would make things less abstract, maybe :) In the initial form of the pattern, it can be used even in PHP, I guess, which is not a very AOP-supporting language :)

    All that said, in production Java code, I guess lots of people may wish to further clean-up the code and use persistence as an aspect.

    I am going to write such demo code, too and post it here.

    Thanks, again.
  4. How does this apply to ORM's[ Go to top ]

    I am jot a Java guy. I am primarily VB and Python. There are several object relational mappers out there for Python (sqlobject, modeling core) as well as java (hibernate being the one that I have heard the most about).

    What I am trying to figure out is tying DO validation and persistence via an ORM together.

    Could someone explain to me how (or if) this pattern is applicable to ORM's?
  5. How does this apply to ORM's[ Go to top ]

    I am jot a Java guy. I am primarily VB and Python. There are several object relational mappers out there for Python (sqlobject, modeling core) as well as java (hibernate being the one that I have heard the most about).What I am trying to figure out is tying DO validation and persistence via an ORM together. Could someone explain to me how (or if) this pattern is applicable to ORM's?

    This is a common point of confussion. ORM frameworks do not provide a DAO layer.

    First, to use DAO/PDO/etc you need to have a Domain Model. Not all applications have a domain model or should have one. Neither does it depend on the "size" of the application. An application can be fairly large and complicated but - not need a DOM. The cutting point here is - how many business rules do you have? How much sense does your application make, without explicitely considering data in the persistent storage?

    Now, if you decide that you do need a domain model and build one - then the whole sense of DAO/PDO/etc is to exctract persistence-related code out of your domain model.

    Please, note that using an ORM framework, in no way means that no persistence code is being written. It just means that (at best) the code written is object-oriented rather than raw SQL. With Hibernate, you still write HQL code.

    As far as your Domain Model entities are concerned - whether the persistence code is object-oriented, SQL, some XML processing or whatever - does not really matter. DAO is all about de-coupling persistence code from the domain model code - no matter what the persistence code is. A well-implemented DAO, will, actually, allow me to mix and match an ORM approach (e.g. Hibernate), plain-SQL, non-DB persistent locations (LDAP, plain files, XML etc) and make it in a transparent way, without affecting my Domain Model.

    Where DAO/PDO and their brothers come irreplacable is during the unit-tests. Because my Domain Model is decoupled from the persistence, I can test DM logic without a database. An ORM framework can not help, much, with that.
  6. Advantages of PDO over DAO?[ Go to top ]

    I agree that separating persistence logic from business logic is important. However, I can't see the advantage of your pattern implementation over that of say, using data access objects (DAOs) - http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html

    Let's say we want to persist a new Cat object. Using your PDO pattern we'd need to do the following:

    CatManager catManager = ...
    Cat cat = new Cat("Widget");
    cat.setCatManager(catManager);
    cat.getCatManager().save(cat);

    But isn't it simpler to break the association between the Cat and its persistence manager to give the following?

    CatManager catManager = ...
    Cat cat = new Cat("Tigger");
    catManager.save(cat);

    J.
  7. Advantages of PDO over DAO?[ Go to top ]

    James,

    naturally there are similarities between the DAO and and PDO because they both try to solve the same problem and some very smart people were working on DAO :) PDO is, arguably, an enhancement of DAO, reflecting new trends that have emerged after the DAO was intoduced.

    So, PDO is not exactly DAO and there are differences.

    First, DAO pattern often means using Transfer Objects, while, in PDO, Manager works with the entity directly.

    Secondly, DAOs use Factory pattern to loosely couple, while PDO uses Dependency Injection. Arguably, DI is a newer and better way of introducing loose coupling than Factories (for more on why - any literature about DI).

    PDO Managers are statically bound to entities whereas DAOs are instance variables, according to the Sun specification. This is important because, with PDO - manager/entity coupling can be defined only once, on the class level, and then it will work for any instance of the entity. This definition can be further abstracted into a framework and defined in an XML file, so that no code will have to worry about it, ever.

    In the client code:
    blog.getManager.save( blog )
    is much cleaner than
    BlogHibernateManager.save ( blog )

    because, in the first case, which manager is used to persist the Blog entity is indicated just once (and can be done in an XML meta-file, as noted) while, in the latter case client code will have to specify exact implementation every time it needs to save/load/remove/etc. blog, which will be at numerous places.

    What if you want to change the manager implementation, used, application-wide? You will have to go and change it in Java code everywhere you save, load, delete or do any other persistence-related operation.

    Is not that "dirty"?

    Regarding your code: you use new() method for the instantiation of the entity object. Please, pay attention that PDO does not do that. It is crucial. A lot of times, you do not have an option to instantiate object with the new keyword.

    For example, if you use Hibernate - it is not an option. Hibernate instantiates object itself. There is no way, in Hibernate, to instantiate an object and then tell Hibernate to just populate it.

    That's why the sample code in PDO looks like:
    blog = (BlogImpl) BlogImpl.getManager().load ( "John" );

    and not some other way.

    Even if not everybody agrees that Hibernate is a de-facto standard, for sure it is the persistence framework of choice for a lot of projects and the pattern used for the separation of concerns better be friendly with Hibernate, right?

    Even if you do not use Hibernate, you may be using a DI framework like Spring. DI frameworks do not let you explicitly instantiate objects, either. They want to do it themselves.

    I hope, I answered your questions.
  8. Advantages of PDO over DAO?[ Go to top ]

    First, DAO pattern often means using Transfer Objects, while, in PDO, Manager works with the entity directly.

    The DAO pattern doesn't mandate TOs, so there's nothing to stop your DAOs working with entities directly. I've never actually worked on a project that has required TOs.
    Secondly, DAOs use Factory pattern to loosely couple, while PDO uses Dependency Injection. Arguably, DI is a newer and better way of introducing loose coupling than Factories (for more on why - any literature about DI).

    Again, the DAO pattern doesn't mandate the use of abstract factories. On my current project we're using Spring to inject DAOs into the service tier (setter stylee), so any service that requires a particular DAO simply declares a setter method for it, e.g. setSomeDAO(SomeDAO dao) and Spring does the rest.

    Moreover, the PDO pattern implementation you've provided doesn't appear to be anything more than a factory pattern in which each entity is responsible for providing its 'persistence manager' for clients. Your inner 'persistence manager' interface is a DAO!
    ... in the latter case client code will have to specify exact implementation every time it needs to save/load/remove/etc. blog, which will be at numerous places. What if you want to change the manager implementation, used, application-wide? You will have to go and change it in Java code everywhere you save, load, delete or do any other persistence-related operation.Is not that "dirty"?

    There are clearly ways to avoid this scenario without mandating that each entity class maintains a static reference to its DAO. Typically, a DAO will be defined by an interface for which one or more concrete implementations exist. If client code is written in terms of the DAO interfaces (not concrete implementations), then it becomes trivial to change the implementation used. For a project using DI, you simply 'reconfigure' the DAO implementation type - in Spring this would require updating the value of a single XML attribute. For projects using abstract factories, you can simply modify the factory to return the appropriate DAO type.

    Also, have you applied this argument to your PDO implementation? You define a Blog interface and an inner BlogManager interface. But because your BlogImpl maintains a static reference to a BlogManagerImpl your client code will be littered with BlogImpl references! And you yourself have pointed out the disadvantages of ("dirty") coding to concrete types rather than to interfaces. The fact that you have to cast a Blog to a BlogImpl begs the question: what's the point of the Blog interface?
    Regarding your code: you use new() method for the instantiation of the entity object. Please, pay attention that PDO does not do that. It is crucial. A lot of times, you do not have an option to instantiate object with the new keyword.For example, if you use Hibernate - it is not an option. Hibernate instantiates object itself. There is no way, in Hibernate, to instantiate an object and then tell Hibernate to just populate it.

    Yes there is (from Hibernate's Session Javadoc):

    load

    public void load(Object object,
                     Serializable id)
              throws HibernateException

        Read the persistent state associated with the given identifier into the given transient instance.

        Parameters:
            object - an "empty" instance of the persistent class
            id - a valid identifier of an existing persistent instance of the class
        Throws:
            HibernateException
    That's why the sample code in PDO looks like: blog = (BlogImpl) BlogImpl.getManager().load ( "John" );and not some other way.

    So how do you create a new, transient instance of an entity using PDO? Does your pattern also require that an entity is a factory for creating instances of itself?
    ... Even if you do not use Hibernate, you may be using a DI framework like Spring. DI frameworks do not let you explicitly instantiate objects, either. They want to do it themselves.

    That's a sweeping statement! There will be parts of your application - typically long lived - that you might like a DI 'container' like Spring to instantiate. But that certainly doesn't mean you can't use the new operator for other parts! My current project uses Spring and Hibernate and we still use the new operator for entities, etc.

    J.
  9. Advantages of PDO over DAO?[ Go to top ]

    James,

    I am sorry if I am wrong, but somehow I have an impression that you have a very strong pre-determined opinion, so I am not sure that whatever I may reply - it is going to matter for you. Yet, I am going to give it one more try.

    From my viewpoint, you are messing a term "DAO" with the Sun design pattern "DAO". Even though the term has been introduced in the pattern, the term and the pattern are not the same.

    Please, take one more look at the pattern description at the URL, you posted yourself:
    http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html

    In one-paragraph "solution" the Sun pattern states that the idea of the pattern is to extract data-access code from the business object. If you see it as the whole pattern - you are right, but I don't. It's too vague of a statement. OK, extract - how? Pattern should give a _solution_ not just a goal. That "solution" is too vague. And Sun understands that because in the next several pages they have two diagrams and code samples of HOW EXACTLY. Putting one and one together - you have to treat all of that as the "solution" and hence the pattern. You can not say that DAO pattern is just the vague suggestion and you can implement it using DI instead of Factories. Sun DAO Pattern solves the problem with Factories and they have specific code sample of how - it is a fact.

    You talk about your experience and how you have "implemented DAO with Spring". Well, my friend, gotta tell you the truth - then you are not using Sun DAO pattern. I surely agree that you are doing the right thing - that's exactly what I am trying to say with PDO that people find alternative way more practical than the original DAO, but, I am sorry - you are _not_ using Sun DAO pattern.

    I can, partially, agree that the managers of the PDO pattern play the same role as DAO objects in Sun DAO pattern. I just don't like the name, because 1) it gives associations with the Sun pattern and people get confused 2) the term DAO has become so broad and burdened that it means just about everything, now.

    The code fro, Sun DAO pattern and PDO pattern are fundamentally different in the solution part (not the goal, everybody knows what the goal is - that's no news), hence I can not see why PDO is the same as DAO and neither agree.

    Let's be honest for a moment. You give an average Java programmer Sun DAO pattern link and tell him to implement Domain Layer according to the pattern, and then you give the link to PDO pattern and show its sample code - do you think the result will be the same? Which would you rather have? But, please, do not mention Spring and that you would do it even better with Spring. I believe that, but pattern can not refer to one specific product. I do not think it would be correct.

    Now two cents regarding your more specific comments:
    1) Well, thank you for indicating to the load(Object object, Serializable id) method. I admit, I have not seen it before. It is not mentioned in any Hibernate book, even the one written by Gavin. That's strange but so far - looks like it is going to work.

    That said - it does not solve the problem in general. Query result objects are still created by Hibernate. And queries are definitely much more useful, used more often than loading a single object. Don't you agree? Neither is it very nice too hook-up with the object initialization and do some immediate post-processing, because when you ask Hibernate for an object - it may come from a hibernate session (usually - unique only in a thread), from cache (not all are thread-safe) or directly from a database. There is no easy way to tell - where you are going to get an object from. So, when two threads get objects from Hibernate, generally, their identity equality is not guaranteed and you may run in a lot of problems.

    2) You say that dirtiness can be avoided if each entity maintains a static reference to its DAO. But Sun Pattern does not say DAO is statically bound, quite on contrary. So, again - you are giving the right solution but it is much closer to PDO and does not have too much to do with DAO as in Sun DAO pattern.

    Next you say that PDO has the same problem because my sample code casts to BlogImpl. No offense, but I think you got a little bit excited there and messed Blog class with BlogManager class. Casting to BlogImpl has nothing to do with the dirtiness because it was the Manager that we wanted to hide-off the implementation of, not the Blog entity. I am not casting, anywhere, to BlogManager and there is only one line of code in main() that mentions the actual implementation, the rest of the sample code is absolutely free of BlogManager implementation information. Even that one line of code can, very simply, be extracted into an XML configuration, if I wanted to make sample more complicated.

    3) I can not agree, either, to your comment that PDO entities are factories to managers. Sorry but, that just does not make any sense. Both Abstract Factory and Factory Method patterns define a way to provide code with specific implementation of objects, from a group of related options, depending on circumstances. PDO entities do not have any logic for deciding which implementation is adequate in which case (the primary functionality of Factory classes) so there is no way, whatsoever you can make that claim.

    The technique used is the Context IoC, introduced by Sony Matthew, at its purest. I used it because it is very simple, clear and does not need any third-party product or knowledge of such product. But how a Manager is associated with the Entity, in PDO, is clearly a Dependency Injection and has nothing, whatsoever to have with factory patterns.

    4) How do I create a new transient object? I guess that was just a sarcastic, rhetorical question. It is quite obvious that PDO does not put any constraint on objects that do not have persisted state in the storage, yet. You can create them with "new", "factory", wiring through DI, or whatever else depends on your current local weather.
  10. Advantages of PDO over DAO?[ Go to top ]

    ... You can not say that DAO pattern is just the vague suggestion and you can implement it using DI instead of Factories. Sun DAO Pattern solves the problem with Factories and they have specific code sample of how - it is a fact.

    I think this just comes down to a difference of opinion. I do believe that the concise solution adequately describes the DAO pattern and that I can implement it using a variety of strategies. If I don't use the automatic DAO code generation strategy, does that mean I haven't implemented the pattern? My point of view is summed up nicely in Chapter 6 of Core J2EE Patterns: Best Practices and Design Strategies: "Strategies provide an extensibility point for each pattern. Developers discover and invent new ways to implement the patterns, producing new strategies for well-known patterns." Following this, another strategy for the DAO pattern could be defined as "Static Instance on Entity Type for Data Access Objects Strategy" :)
    ... but, I am sorry - you are _not_ using Sun DAO pattern.

    Ok, I concede, I'm using the Sun++ DAO pattern :)
    I can, partially, agree that the managers of the PDO pattern play the same role as DAO objects in Sun DAO pattern.

    Why only partially? I can't see any difference between their respective roles.
    ... 2) the term DAO has become so broad and burdened that it means just about everything, now.

    This comes down to personal experience. I've personally never come across a situation in which the term 'DAO' has been confused with another pattern to the point of being useless. I don't like the name that much, but I've always found it communicates its intent appropriately.
    The code fro, Sun DAO pattern and PDO pattern are fundamentally different in the solution part (not the goal, everybody knows what the goal is - that's no news), hence I can not see why PDO is the same as DAO and neither agree

    The implementation of the goal of the two patterns, i.e. that of the abstraction and encapsulation of access to a data source, is structurally identical: DAO interface == Manager interface. Where the patterns differ is how a client obtains concrete implementations of these interfaces. This is supplementary to the DAO pattern, which "may be implemented using the Abstract Factory pattern" (Factory for Data Access Objects Strategy, Core J2EE Patterns - Data Access Object) or potentially one of a host of other strategies. Conversely, the PDO pattern dictates that each manager is statically bound to its associated entity.
    That said - it does not solve the problem in general. Query result objects are still created by Hibernate. And queries are definitely much more useful, used more often than loading a single object. Don't you agree?

    Yes, I do! My original example illustrated persisting a new, transient instance, rather than loading a persistent instance. Hence, this confusion.
    Next you say that PDO has the same problem because my sample code casts to BlogImpl. No offense, but I think you got a little bit excited there and messed Blog class with BlogManager class. Casting to BlogImpl has nothing to do with the dirtiness because it was the Manager that we wanted to hide-off the implementation of, not the Blog entity.

    None taken, but you're missing my point. PDO dictates that my manager interface is statically bound to its entity type. Therefore, I can only obtain one from a concrete entity implementation, e.g. BlogImpl. If I go to the effort of defining an interface for my entitites, I'm not sure that I like having to reference particular concrete implementations in order to perform some persistence operations. If BlogImpl becomes MyOtherBlogImpl, I have potentially a lot of code to update.
    The technique used is the Context IoC, introduced by Sony Matthew, at its purest. I used it because it is very simple, clear and does not need any third-party product or knowledge of such product. But how a Manager is associated with the Entity, in PDO, is clearly a Dependency Injection and has nothing, whatsoever to have with factory patterns.

    Your implementation of Context IoC is not consistent with the original pattern. In the original article, it is the object that contains the inner context that uses it. In your implementation, it is an arbitrary client of the object that uses the contained context. Put simply, BlogImpl is no more dependent on an arbitrary BlogManager implementation any more than String is dependent on say, StringReader - it's the other way around! Therefore, you are injecting one object into another object that doesn't even need it! Which brings me back to my original point: if the entity that contains the manager doesn't depend on it or use it, why complicate matters by making the association with no obvious benefits?
    How do I create a new transient object? I guess that was just a sarcastic, rhetorical question. It is quite obvious that PDO does not put any constraint on objects that do not have persisted state in the storage, yet. You can create them with "new", "factory", wiring through DI, or whatever else depends on your current local weather.

    It wasn't meant to be sarcastic or rhetorical. As my code example was not directly analogous to yours, things got confused. You talked about not being able to 'new' an instance (as Hibernate does that for you). However, you were talking about persistence instances, I was talking about transient instances, hence the question. Never mind! BTW, the weather's pretty rubbish here :)

    I still don't think you've answered my original question: can you provide any concrete advantage of using PDO over DAO (or, if you prefer, DAO + dependency injection strategy)?

    J.
  11. Advantages of PDO over DAO?[ Go to top ]

    James,

    thank you for your answer.

    It is a little bit hard to argue with you, for me, because I do not, really, disagree with much of what you say. I am afraid, it has more to do with the angle from which we perceive the facts. Since I do not think the angle is that important, following is the honest and straight answer to your main question, made as concise as I could:

    While, indeed, the term "DAO" delivers the idea of abstracting persistence details out of the business objects, clearly and loudly, I have an impression that the same is not true regarding the actual usage strategy.

    Very simply put: if I sit in a room with a bunch of architects and say that I want to use DAOs to make my Domain Objects easily unit-testable, it will be so clear, I run into the risk of looking stupid for wasting everybody's time on stating the obvious.

    However, let's see what may happen on one, unlucky day with a bad weather. Say, some programmer really screwed up. Senior developer (architect, whatever) points him to Sun DAO pattern URL and requests the code to be re-written using the DAOs.

    I find it highly non-determined (based on just Sun description), what the result will be, and in my paranoia, I fear that odds are - it will not be the nice design that we want to get.

    So, under the threat of being seen as a stubborn jerk, I may give up the rank of Pattern on PDO. I do not really care what its rank is. It's not like I invented something totally new :)

    I just think Sun DAO is very vague in the implementation part (not necessarily bad for a pattern, admitted) and its sample implementation - I do not like. Hence, I thought it would be useful something better to be put out, like - PDO (whether it is an independent pattern, better practice of DAO pattern or whatever).

    That's how and why I see PDO useful. Now regarding, if it is useful, indeed:
    if the entity that contains the manager doesn't depend on it or use it, why complicate matters by making the association with no obvious benefits?
    Weeeell, Entity does depend on a manager., just no - on any specific manager, per se. Persistence is an inherent behavior of an entity. What it does not depend on is - the specific mechanism/implementation. Entity does not care about the persistence code but it cares about the services that come from the persistent code.

    One important point: when I say "persistence", I do not just mean the ability of the object to persist/load itself. I mean - any functionality of the object, that involves looking up the database. Say, Blog object, to carry out some of its business functionality, needs to look-up a set of BlogPost objects in the database. The objects it retrieves are BlogPost objects, not Blog objects, but since in any real application you do not have all objects loaded in RAM, all the time, Blog really needs to issue this query. So, dependency is there, and a non-trivial one (!), but Blog really should not care whether the persistence storage, where BlogPosts are kept is an RDBMS, LDAP, native-XML storage, JNDI, flat-files or whatever :)
  12. Advantages of PDO over DAO?[ Go to top ]

    P.S. I liked that "Sun++ DAO pattern" name :-)

    cheers
  13. Advantages of PDO over DAO?[ Go to top ]

    I have to agree. And by doing this, you don't have to have the persistance tied to the domain object at all, thus giving the freedom of using the domain objects by themselves anywhere, not just the application. This makes it more reusable.
  14. Thoughts on PDO vs DAO[ Go to top ]

    I’m late to this discussion, but I’d like to chime in.

    I don’t think the PDO pattern is simply a strategy to implement DAO. If I read the DAO pattern correctly, the transfer object has no knowledge of or dependency on the DAO layer.

    The transfer object is intended to be a serializable POJO. A DAO can just as easily use serializable domain entities rather than separate transfer objects (assuming the domain entities can fulfill the other roles of the transfer object in the J2EE pattern language).

    The PDO domain object. as stated in the article, differs from a POJO on it’s persistence interface. This is in effect merging the responsibilities of a DAO object within a domain object. I would think this is significant enough of a structural change to merit it’s own pattern, as it does have other advantages/consequences.

    For example, we may intuitively want to keep the persistence interface out of the domain object. Aside from the aesthetic appeal (yes I know, a poor reason) of having disjoint domain/persistence layers, we may want to discourage programmers from using the persistence interface outside of the domain logic layer in the name of loose coupling (wherever pragmatic, of course).

    The above can simply be addressed by providing a narrower interface to domain entities where appropriate. So the above concern is hardly fatal to the pattern.

    Now, a POJO-based approach to domain entities (which I think the DAO is) gets complicated when we deal with domain objects that aggregate other domain objects. When logic or constraints on a domain object need to be applied with respect to a subset of the aggregated objects, the DAO approach would have us suck in all aggregate objects before we can perform the operation.

    Otherwise, we would have to split up logic that we would naturally put in one domain POJO into business logic objects (which typically have access to DAO’s to fetch domain objects from persistence). But then, this encourages the anemic domain object anti-pattern.

    With the PDO approach, we can actually query for the particular objects we need from within the domain object by virtue of the Manager interface.
      
    This is not to say that we need to blindly reinstate entire object trees to perform certain operations specific to a domain object when using a DAO approach, or that we need anemic domain objects. With ORM framework support, the solution can be quite elegant.

    For example, with hibernate the collections that are loaded from persistence are automatically replaced with hibernate’s own implementation that supports lazy loading. But if we want a generic solution, we can’t assume the existence of this kind of facility.
                
    Even with Hibernate’s replacement of collection implementation, I wonder what the effect of an operation like Set.contains() is. Does it load all objects and check for membership, or does it simply perform a query,or better yet - can the user decide? Something to investigate when I have time, I suppose…