Design Patterns Java - Composite Php

1) At the beginning.

Let's imagine situation that we have some set of products for example in the shop. In our example we have class "Product" as representat of shop's product

Sometimes we would like to sell many products at once. This is representing by class "Pack" which contains array of "Product"


public class Product
{
    private double cost;

    public Product(double cost)
    {
        this.cost = cost;
    }

    public double getCost()
    {
        return cost;
    }
}

import java.util.List;
import java.util.stream.Collectors;

public class Pack
{
    private List<Product> products;

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

    public double getValue()
    {
        return products.stream().mapToDouble(Product::getCost).sum();
    }
}





2) What want we to compute in application?

We want to compute cost of production both class "Product" alike class "Pack"

3) How can we compute cost of products in application ?

Let's look for the following code:

chcemy obliczać wartość(koszt) tych obiektów - otrzymujemy dla przykładu jeden z tych obiektów
ale nie wiemy jakiego jest typu musimy sprawdzać typ i wyliczać koszt danego obiektu


import java.util.Arrays;
import java.util.List;
import java.util.Random;

public class Client
{

    public static void main(String[] args)
    {
        Product product = new Product(13.02);
        Pack pack = new Pack(Arrays.asList(new Product(13.02), new Product(5.67), new Product(2.12)));

        List<Object> products = Arrays.asList(product, pack);

        Object randomProduct = products.get(new Random().nextInt(products.size()));

        double value = 0.0;

        if (randomProduct instanceof Product)
        {
            value = ((Product) randomProduct).getCost();
        }
        else if (randomProduct instanceof Pack)
        {
            value = ((Pack) randomProduct).getValue();
        }

        System.out.println(value);
    }
}




We want to compute of cost of these objects. We want to receive some object we don't know what is the type so we check this and invoke proper method.

It's not the best solution.

4) How we can improve this?

Let's notice that "Pack" we can treat as "Product". In fact it is a product - strictly speaking a compound product contains with many other products.

We should create a common interface which will implement both this classes. Let's call it "getCost".

Let's see the code in step2.