1
votes

Recently I have really focused on writing clean code and implementing designs and I have stumbled accross a situation where I have several options but cannot decide which one is the appropriate one. I am working on a software that requires persistence on a collection of objects. I decided to implement a DAO Pattern. The thing is that persistency could both be Json OR Xml so I implemented it this way:

I created a Generic DAO:

public interface GenericDao<T> {
    public boolean add(T type);
    public boolean change(T type);
    public void delete(T type);
}

Then I created a CarDAO:

public interface CarDao extends GenericDao<Car> {
    public Car getByIdentificationNumber(int id);
    public void process();
}

For JSON persistence:

JsonGenericDao:

public class JsonGenericDao<T> implements GenericDao<T>  {

    public boolean add(T type) {
        // implement ADD for json
    }
    public boolean change(T type) {
        // implement Change for json
    }

    public void delete(T type) {
        // implement Delete for json
    }
}

JsonCarDao:

public class JsonCarDao extends JsonGenericDao<Task> implements CarDao {

    public Car getByIdentificationNumber(int id) {
        // Implement logic
    }

    public void process() {
        // Logic
    }
}

JsonCarDao extends JsonGenericDao to include the Add, Change, Delete and it also provides additional methods.

The same way is implemented XmlGenericDao and XmlCarDao.

So I end up with the possibility of using XmlCarDao OR JsonCarDao depending on the persistence I want to use.

When implementing the persistence, I used JAXB for XML and Gson for JSON. I made an EntityCollection<T> class to store the objects inside and I would convert this collection to either XML OR JSON depending on the persistence used and I would retrieve the information from the file to this collection, change what needs to be changed and then rewrite the file.

There are two ways I can implement it:

Option 1:

I could implement the persistence using Gson inside JsonGenericDao and do the same for JAXB inside XmlGenericDao.

Option 2:

I can create an interface Persister<T> and write two classes that implement this interface, therefore JsonPersister<T> and XmlPersister<T> with methods such as update(T type) and acquireAllFromFile(), one of which is going to rewrite the whole file with the new data, and the other one is going to retrieve the information from the file. (Same thing could be done in Option 1 but without making the additional classes)

Then inside JsonGenericDao<T> I can use: JsonPersister<EntityCollection<T>> and inside XmlGenericDao<T> I can use: XmlPersister<EntityCollection<T>> therefore packing everything.

The problem here though is thinking about this, it would mean that I can get rid of JsonGenericDao and XmlGenericDao and implement a single PersistenceGenericDao which is going to use a Persister interface inside its CONSTRUCTOR to specify if JsonPersister should be used or XmlPersister should be used. It would basically be a combination of DAO and Strategy Pattern. Now this seems like something I can do.. but it also appears to me that it messes up my initial DAO design. Is it an appropriate thing to do or is it bad practice?

1

1 Answers

1
votes

I think your option 2 actually looks like the GoF Bridge Pattern. XmlPersister/JsonPersister are ConcreteImplementors. PersistenceGenericDao is Abstraction, JsonCarDao is RefinedAbstraction.

So the idea actually makes sense. See What problems can the Bridge design pattern solve? to check if you really need the pattern or not.

If you only plan to use XML or JSON persistence, I personally would go with option 2. If you compare JsonCarDao with XmlCarDao, the only difference between them will probably be the mechanics of saving/loading data from some resource (JSON vs. XML). The rest of the logic will probably be pretty much the same. From this point of view, it is reasonable to extract the "saving/loading" into specific implementors and have one generic class for the rest of the DAO logic.

However if you consider relational or NoSQL database persistence, this might not fit that well. Because the DAO logic will probably be different. A method like findById will be pretty different in a relational DAO (query in the DB) compared to a JSON DAO (load data from a JSON file and search the collection of objects for an object with the given ID). In this situation, RelationalPersistence will probably not be very efficient.