Code Smell of the year

Message Chain

Message Chains violates the law of demeter. They increase the dependencies through the system.


class InvoiceTest {

    Invoice invoice;

    @BeforeEach
    void setUpInvoiceWithShippingCosts() {
        invoice = new Invoice(new Customer(new Address(new Country())));
    }

    @Test
    void ShouldReturnPriceOfOneItemWithShippingCost() {
        InvoiceItem item = new InvoiceItem(100);
        invoice.addItem(item);
        assertEquals(110, invoice.getTotalPrice());
    }

    @Test
    void ShouldReturnPriceOfTwoItemWithShippingCost() {
        InvoiceItem item = new InvoiceItem(100);
        invoice.addItem(item);
        invoice.addItem(item);
        assertEquals(210, invoice.getTotalPrice());
    }


}


public class Invoice {

    static final double SHIPPING_COST_OUTSIDE_EU = 10;
    private List<InvoiceItem> invoiceItems = new ArrayList<InvoiceItem>();
    private Customer customer;

    public Invoice(Customer customer){
        this.customer = customer;
    }

    public void addItem(InvoiceItem invoiceItem){
        invoiceItems.add(invoiceItem);
    }

    public double getTotalPrice(){ 
        double invoiceTotal = 0;

        for (Iterator iterator = invoiceItems.iterator(); iterator.hasNext();) {
            InvoiceItem invoiceItem = (InvoiceItem) iterator.next();
            invoiceTotal += invoiceItem.getSubTotal();
        }

        if(!customer.getAddress().getCountry().isInEurope()){
            invoiceTotal += SHIPPING_COST_OUTSIDE_EU;
        }
        return invoiceTotal;
    }
}


Hint: Objects should only interact with their nearest neighbours


You can fork it here from Github.

This is step one of the second part of the Refactoring kickstart beginner series. Here is step 2.