Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to propely design a combination of many sub-classes?

I have a parent class - Product

public abstract class Product {}

And 3 sub-classes which extends it:

  1. public class Vinyl extends Product {}

  2. public class Book extends Product {}

  3. public class Video extends Product {}

All sub-classes override the preview() method with their specific implementation. Now, I have a new design demand: I need to define a combo item of vinyl & book which also has a preview() method (which is a combination of vinyl & book). In the instructions it says I can create Interface\ class field member or any implementation I want to support it, but I'm not sure how exactly.

Is the new design should also be implemented with inheritance or should I change the current design?

like image 611
Nimrod Avatar asked Jul 23 '16 15:07

Nimrod


1 Answers

Is the new design should also be implemented with inheritance or should I change the current design?

The new design can be implemented purely with inheritance. But the real problem with this would be that you would have way too many subclasses. You could easily create a new subclass of Product called VinylBook and be done with it. But what happens when you have to introduce another combination, say VinylVideo. You would have to create a new subclass for this as well and so on.

The solution is to use inheritance and composition together. The Composite pattern would be a good fit for this problem. According to wikipedia :

The composite pattern describes that a group of objects is to be treated in the same way as a single instance of an object. Implementing the composite pattern lets clients treat individual objects and compositions uniformly.

Let's start by defining a CompositeProduct

public class CompositeProduct` extends Product {
     private List<Product> products;

     public CompositeProduct(List<Product> products) { this.products = products }

     public String preview() {
          String previewText = "";
          for(Product product : products) { previewText+=product.preview(); }
          return preview;

     }
}

You now have composite product that behaves as if it is one single product allowing you to create combo products on the fly without the need to create a new subclass for each combo.

An example of how you can create products on the fly :

Book book = new Book();
Vinyl vinyl = new Vinyl();
List<Product> products = new List<>();
products.add(book);
products.add(vinyl);
CompositeProduct vinylBook = new CompositeProduct(products);

You can also take a look at the Decorator pattern if you are looking at adding additional behavior to your products on the fly.

like image 151
Chetan Kinger Avatar answered Oct 16 '22 16:10

Chetan Kinger