2

I am wondering if there is a design pattern for such problem:

Let's say we are building a web shop for a doors and windows manufacturer, where customer has a catalog (list) of products, from which he can choose some and customize them, before placing an order.

Each product has it's properties defined, like name, price, description. Obviously, the customer is not allowed to change any of these properties. But there is a space to customize the product. When he chooses a window, then he can choose it's colour, dimensions, perhaps a color of glass and choose some additional features. When he chooses doors, then he can choose a color, dimension, but also a type of the lock.

First idea that came to my mind is:

  1. Create products definitions classes (WindowDefintion, DoorsDefinition), which hold information about the name, price, description. These are listed in a catalog
  2. Create product instances classes (Window, Doors), which hold reference to the product, but also add customizable fields, which are specific to certain instance.

Disadvantages are perhaps silly, because it is mostly about creating a definition class for each instance class, but this involves more doubled amount of database tables and repositiories as well. I was just wondering if there is some other solution?

This example is not the case. I am using it to ease understanding of the problem. In the case, products don't have a good common generalization, which a Product would give in this case (good for having name, description and price properties).

1

Your abstractions appear too fine grained and you are thinking about modelling your persistence layer in the same way as your domain.

There is trade off to be made here.

On the one hand if you model your products like this in a database, you will indeed end up with a larger number of tables, each change to a product will require schema, repository, domain and consumer/application changes. This is IMO quite a brittle design.

If you make your schema less aware of product implementations, instead opting to store custom values in a more key/value fashion for each product customisation, each change to a product will likely not require schema and repository changes, only domain and application changes. It will complicate things like searching/retrieval and rehydration of domain objects but this is typically what a service layer and domain model is for, abstracting away the specifics of persistence.

It depends on your application requirements which aren't really clear but I'd always lean towards option number two.

I would focus on modelling an abstract Product type containing the common elements (ids, names, descriptions, prices) and use something like a decorator or builder pattern to add the product specific things into a collection which is accessed using subtype properties created by the patterns.

Persistence/Repository layers would only require knowledge to Save/Load the collection into the proper types which could be done using a Factory.

As requirements change and complexity increases for product options and customizations, it becomes far easier to manage this kind of model where your logic is in the domain layer and not reflected in your persistence layer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.