Design Patterns – Getting a Collection of Objects from Different Sources

design-patternsobject-oriented-design

I've got a class Shop which contains a collection of Item objects. You can create a shop in two different ways:

  1. Create a shop filled with test data (for debug purposes);
  2. Create a shop by reading the data from file

I also need to write the shop back to file.

There is any pattern that can elegantly wrap this behavior?

This is the implementation right now (in Java):

class Item {

    public final String name;

    public Item(String n) {
        name = n;
    }

}

class Shop {

    public List<Item> items;

    private Shop() { 
        items = new LinkedList<>();
    }

    public static Shop generateTestData() {
        Shop shop = new Shop();
        shop.items.add(new Item("Product A"));
        shop.items.add(new Item("Product B"));
        shop.items.add(new Item("Product C"));
        return shop;
    }

    public static Shop readFromFile(String filepath) {
        // read from file
    }

    public static void writeToFile(Shop shop, String filepath) {
        // write to file
    }

}

N.B. I considered applying a sort of Prototype pattern in this way: I create a static instance of the Shop filled with test data, then the user can get a copy of that and modify it as he/she wants. Is it a good idea?

Best Answer

In short, you are missing the support of a dedicated layer (abstraction) addressed to facilitate the access to the data and to its differents storages. The DAL

The DAL allow you to decouple your actual Shop from its storage. The layer stablishes a well-defined separation of concerns (responsabilities).

The design of the DAL usually vary among projects. However, I think that DAO and Repository patterns could do the job perfectly in this specific case.

In terms of abstraction, DAOs and Repositories belongs to different layers. Being the Repository the higher and the DAO the lower

Bussines Layer -> Repository -> DAO

It's not necessary to implement both. Whether you implement one of them or both, the key here is the single responsability principle.

Translated to your specific case, you can do something like this:

ShopRepository:

  • FileShopDAO
  • InMemoryShopDAO
  • DataBaseShopDAO
  • etc...

For every specific situation you could use one of the DAOs

  • Testing : InMemoryShopDAO
  • Production : DataBaseShopDAO or FileShopDAO

The key here is that all the DAOs implement the same interface. For instance: ShopDAO.

public ShopRepository {

  private ShopDAO dao;

  public ShopRepository(ShopDAO dao){
    this.dao = dao;
  }

   //Data access methods....
}

Choose according to the requirements and your preferences.

For instance, you may decide to go with 3 different Repositories rather than 3 different DAOs. That's up to you.

Related Topic