Design Patterns Java - Composite Php

1) What have we done?

As we said we create the common interface "Product"

Previous concrete class "Product" now we will call "SingleProduct"


public interface Product
{
    double getCost();
}

public class SingleProduct implements Product
{
    private double cost;

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

    public double getCost()
    {
        return cost;
    }
}

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

public class Pack implements Product
{
    private List<Product> products;

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

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




2) What have we achieved ?

Let's look on client code


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

public class Client
{
    public static void main(String[] args)
    {
        Product product = new SingleProduct(13.02);
        Pack pack = new Pack(Arrays.asList(new SingleProduct(13.02), new SingleProduct(5.67), new SingleProduct(2.12)));
        Pack compoundPack = new Pack(Arrays.asList(
                new Pack(Arrays.asList(new SingleProduct(4.32), new SingleProduct(11.62))),
                new SingleProduct(2.35)
        ));

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

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

        System.out.println(randomProduct.getCost());
    }
}




We don't have to to check types, Client doesn't have to differentiate type "Pack" and "SingleProduct".

Therein lies "Composite" pattern. It allows objects with relation whole-part treat compound and single object in the same way.

Let's notice that now when we treat these objects the same we can create more compound objects like "compoundPack".
Before we couldn't do this, it's another plus.