Sonntag, 27. Oktober 2013

DRY unit tests

Unit tests are written in the same quality as the production source code therefore, they follow the DRY principle. To achieve this goal it is sometimes necessary to enhance unit tests with a new runner for the JUnit tooling. JUnitParams adds a new runner to provide easier and more readable unit tests. By using JUnitParams you have to write less source code for your unit tests through short cuts like the $(…) method. The following example compares JUnitParams with a regular written unit test.

Class under test

public class Message {

    private final String message;

    public Message(final String message) {

        if(null == message || message.isEmpty()) {

            throw new IllegalArgumentException("Message is null or empty!");
        }

        this.message = message;
    }

    public String getMessage() {

        return message;
    }
}

Regular unit test

public class MessageTest {

    @Test
    public void testMessageHello() {

        final Message message = new Message("Hello");

        Assert.assertEquals("Hello", message.getMessage());
    }

    @Test
    public void testMessageWorld() {

        final Message message = new Message("World");

        Assert.assertEquals("World", message.getMessage());
    }

    @Test(expected= IllegalArgumentException.class)
    public void testMessageIsNull() {

        final Message message = new Message(null);
    }

    @Test(expected= IllegalArgumentException.class)
    public void testMessageIsEmpty() {

        final Message message = new Message("");
    }
}

Unit test with JUnitParams

@RunWith(JUnitParamsRunner.class)
public class MessageParameterizedTest {

  private static final Object[] getMessageValue() {

        return $(

            $("Hello"),
            $("World")
        );
    }

    private static final Object[]  getInvalidMessageValue() {
        return new String [] [] {{null},{""}};
    }

    @Test
    @Parameters(method="getMessageValue")
    public void testValidMessages(final String messageParam) {

        final Message message = new Message(messageParam);

        Assert.assertEquals(messageParam, message.getMessage());
    }

    @Test(expected=IllegalArgumentException.class)
    @Parameters(method="getInvalidMessageValue")
    public void testInvalidMessages(final String messageParam) {

        final Message message = new Message(messageParam);
    }
}


Der Rechtshinweis des Java Blog für Clean Code Developer ist bei der Verwendung und Weiterentwicklung des Quellcodes des Blogeintrages zu beachten.

Dienstag, 27. August 2013

Policy Driven Implementation

Dominant design patterns for domain models are the strategy and the composite pattern. To build rich domain models with both patterns is an honest achievement. My focus in the following explanation  is on the strategy pattern which is the base for the implementation of policies. Policies are true friends in case of designing an application programming interface. Policies guarantee the possibility to alter algorithms in the background without the need to touch a previous released interface. It might be true, that this is only one part of the story. To ensure extensibility you need another design pattern which uses overriding in a subclass. As you already assumed, it is the template method or factory method pattern.

Duke proudly presents the definition for the strategy pattern:

Define a family of algorithms, encapsulate each one and make them interchangeable.
The strategy pattern lets the algorithm vary independently from clients that use it.
[Gang of Four]


The power of design patterns is hidden in their combinations. But be aware: A design pattern should be applied only when it’s needed! Well, don’t worry now. Look first to solve your business problem and then look for a combination of patterns to ensure that your software is reusable and extensible.

The strategy and template method patterns are a strong combination to write software which meets the criteria of the Open Closed Principle (OCP). The strategy makes the algorithms changeable and the template method pattern ensures the extensibility without touching an existing implementation. For sure it’s difficult to see such combinations in a deep object oriented class hierarchy, but on the other hand a few principles will help you to build robust object oriented software. Consider first the usage of the template or factory method pattern and then decide how you can vary your algorithms in your system context which will lead to a policy driven implementation.

The following example is the implementation of a billing class with two variants. The first variant is the implementation of a 19% tax billing class and the second one is a 7% tax billing class. The implementation uses the template method pattern to determine the tax rate and the strategy pattern to implement the tax rate read strategy.

Billing base class:

package org.ccd.policy;

import java.math.BigDecimal;

abstract class Billing {

    private final BigDecimal price;   
   
    protected Billing(final BigDecimal price) {
       
        this.price = price;
    }
   
    /**
     * Calculate the price including
     * the tax rate.
     *
     * @return price * tax rate
     */
    public BigDecimal calculate() {       
        return price.multiply(tax());
    }

    /**
     * The tax rate method.
     *
     * @return tax rate
     */
    protected abstract BigDecimal tax();
   
    /**
     * The TaxPolicy interface.
     */
    protected interface TaxPolicy {       
        public BigDecimal rate();
    }
}

Billing min tax rate subclass:

package org.ccd.policy;

import java.math.BigDecimal;

public class BillingMinTaxRate extends Billing {
  
    public BillingMinTaxRate(final BigDecimal price) {      
        super(price);
    }
  
    @Override
    protected BigDecimal tax() {
      
        return new TaxPolicy() {

            @Override
            public BigDecimal rate() {
              
                // read tax rate from database,
                // it's a fake right here!
                final BigDecimal taxRate = new BigDecimal("1.07");
              
                return taxRate;
            }
          
        }.rate();
    }
}

Billing max tax rate subclass:

package org.ccd.policy;

import java.math.BigDecimal;

public class BillingMaxTaxRate extends Billing {
   
    public BillingMaxTaxRate(final BigDecimal price) {       
        super(price);
    }
   
    @Override
    protected BigDecimal tax() {
       
        return new TaxPolicy() {

            @Override
            public BigDecimal rate() {
               
                // read tax rate from database,
                // it's a fake right here!
                final BigDecimal taxRate = new BigDecimal("1.19");
               
                return taxRate;
            }
           
        }.rate();
    }
}

Billing test class:

package org.ccd.policy;

import static org.junit.Assert.*;
import org.junit.Test;
import java.math.BigDecimal;

public class BillingTest {

    @Test
    public void testBillingMinTaxrate() {
       
       final Billing billingMinTaxRate =
            new BillingMinTaxRate(new BigDecimal("10.00"));
       
        assertEquals(new BigDecimal("10.70").doubleValue(),
                billingMinTaxRate.calculate().doubleValue(),
                new BigDecimal("0.00").doubleValue());       
    }
   
    @Test
    public void testBillingMaxTaxrate() {
       
        final Billing billingMaxTaxRate =
             new BillingMaxTaxRate(new BigDecimal("10.00"));
               
        assertEquals(new BigDecimal("11.90").doubleValue(),
                     billingMaxTaxRate.calculate().doubleValue(),
                     new BigDecimal("0.00").doubleValue());       
    }
}



Der Rechtshinweis des Java Blog für Clean Code Developer ist bei der Verwendung und Weiterentwicklung des Quellcodes des Blogeintrages zu beachten.

Samstag, 24. August 2013

Thinking about caching

I have heard it multiple times: Caching is evil! The risks and benefits of caching are obvious. The main risks using a caching strategy are to work with stale data and to waste memory. On the other hand the benefits are reducing database access and increasing performance by reading pre calculated data. The Java EE entity manager (JPA) uses a first level cache and optional a second level cache. The first level cache is related to the persistence context which means the cache is valid between a single transaction. After the transaction commits or possibly after a rollback the first level cache is gone.


The second level cache (L2-Cache) has a longer lifetime. The second level cache is independent of a particular entity manager instance and the related transactions. Using a second level cache reduces database access to gain better performance. The second level cache should be configured that the count of maintained entities are limited and that the cache is refreshed automatically after an expired timeframe. To reduce the problem of stale data put mainly entities with static data in the second level cache. Static data are system data which could be application profile data, labels of an I18n strategy or fixed GUI related data which alter seldom.

The rule of thumb is:

Caching is valuable without risk for static data which are not refreshed during program execution. Caching can be evil for frequent altered data even in a transactional context.

Caching to reduce database access is one part of the story, but caching could also lead to better performance within the application itself. Java has several collection classes which supports safer caching to avoid stale data. A good example is the WeakHashMap.  An entry in a WeakHashMap will automatically be removed when its key is no longer in ordinary use.

Since Java 5 the LinkedHashMap can be used as a LRU Cache (last recently used cache). By overriding the “removeEldestEntry” method to implement a policy for removing stale mappings automatically when new mappings are added. There are even more sophisticated caching solutions (e.g.: Ehcache) available which handle evict and refreshing better as the simple Java API implementations.

The conclusion is:  Caching could be evil when wrongly considered and valuable when considered with care. Therefore use caching with care!

Donnerstag, 9. Mai 2013

Tell don't ask

Over the years data transfer objects which are generally full with getter and setter are used without business logic. Technologies like J2EE lead to see them as pattern and common development practice. Originally designed to carry data over layers (serializable object) and to be part of an object assemble strategy they mutated to a development practice which can now be seen as an anti-pattern. Okay, we know the danger of getter to retrieve state data to manage the state outside the instance of a class. Smart guys are used to immutable objects by using finals and only getter without any setter, but indirect state changing by retrieving a reference with a getter is still possible and dangerous.

As a developer I have never heard: “Remove all getter, we don’t use them”. There is no coding convention for this topic. I still think it is not possible to live without getter, but I know to follow the way of immutable objects is a good way to write stable software. The usage of defensive copies may help to implement real immutable objects. Think about using the clone() method and in case of collections about deep copying objects. Strategies you can trust, even when race conditions occur.

I share my opinion with experienced developers which it is a good design practice to give the domain objects behavior to expose less state. I know that entities needs getter/setter as the entity manager (ORM technology) expects them, but on the other hand it's a rich implementation practice to give entities additionally behavior. The annotation @Transient may help you. Don’t see the domain layer as a stupid data heap by putting all business logic in the service layer. Doing this you will break OOP by starting functional programming.

Even in the past, J2EE already propagated to put business logic in CMP/BMP entities. Until today I do not understand why this had not been emphasized and written down in red bold letters that every developer recognized this fact as an important development practice.There is no doubt that using rich domain objects are in line with OO principles like high cohesion and data hiding.

Following this principle you will not end with a layer of anemic domain objects which are difficult to put into a test strategy. Think about isolation and the power to test rich domain objects which do not allow publishing their state. The design of lean service layer accessing rich domain models which holds the key business logic is an honest achievement which is comfortably implementable with POJOs and the rich set of Java EE annotations.

The evil often begins with some of the Java API classes like the iterator.  The iterator is a vehicle to loop through the collection of state holder. A common practice is to call a getter to get the reference of a collection instance to call the iterator method. How will you test that? Think about isolation and the benefit of louse coupling. The problem occurs when you have developed such a structure and later you write the test case. Tight coupling often makes it impossible to write test cases. Test cases are important. Without test cases no refactoring will happen.

The following example includes a simple division functionality which shows the difference between tell don't ask like software and the opposite. Look at the test class which tests both classes and hopefully gives an impression about the benefits of not using anemic objects.

Anemic division class (not tell don't ask conform):

package org.ccd.tell.dont.ask;

public class AnemicDivision {

    private int divisor;
    private int divident;
   
    public int getDivisor() {
        return divisor;
    }
   
    public void setDivisor(int divisor) {
        this.divisor = divisor;
    }
   
    public int getDivident() {
        return divident;
    }
   
    public void setDivident(int divident) {
        this.divident = divident;
    }
}

Division class (tell don't ask conform):

package org.ccd.tell.dont.ask;

public class Division {

    public int buildQuotient(final int divident, final int divisor) {
       
        assertDivisor(divisor);
       
        return divident / divisor;
    }

    private void assertDivisor(final int divisor) {
       
        if(0 == divisor) {
       
             throw new IllegalArgumentException("Divisor is 0: Leads to divide by zero exception!");
        }
    }
}

Test:

package org.ccd.tell.dont.ask;

import junit.framework.Assert;

import org.junit.Before;
import org.junit.Test;

public class DivisionTest {

    private AnemicDivision anemicDivision;
    private Division division;
    private int quotient;
   
    @Before
    public void before() {
   
        anemicDivision = new AnemicDivision();
        division = new Division();
    }
   
    @Test
    public void testAnemicDivision() {
               
        anemicDivision.setDivident(100);
        anemicDivision.setDivisor(10);
       
        quotient = anemicDivision.getDivident() / anemicDivision.getDivisor();
       
        Assert.assertEquals(10, quotient);
    }
   
    @Test(expected=ArithmeticException.class)
    public void testAnemicDivisionDivideByZero() {
               
        anemicDivision.setDivident(100);
        anemicDivision.setDivisor(0);
       
        try {
       
            quotient = anemicDivision.getDivident() / anemicDivision.getDivisor();
        }
        catch(ArithmeticException arithmeticException) {
                   
            throw arithmeticException;
        }       
    }
   
    @Test
    public void testDivision() {
               
        quotient = division.buildQuotient(100, 10);
       
        Assert.assertEquals(10, quotient);
    }
   
    @Test(expected=IllegalArgumentException.class)
    public void testDivisionDivideByZero() {
               
        quotient = division.buildQuotient(100, 0);
    }
}

Note: There is a difference in semantics between Data Transfer Objects (DTOs) and Value Objects (VOs) therefore, VO should not be an alias name for DTO. Both objects hold data but a VO is identified by its values (enum kind style, no identity but equality) as against to a DTO which can have an identity (unique identifier as attribute).


Der Rechtshinweis des Java Blog für Clean Code Developer ist bei der Verwendung und Weiterentwicklung des Quellcodes des Blogeintrages zu beachten.