samedi 20 juin 2020

Java 8: looking for a design pattern to reduce code duplication

I'm having the following test classes. I'm wondering if there's a design pattern that can reduce the code duplication in the following scenario.

public abstract class BaseTestClass {

    protected String color;

    protected String type;

    protected Product product;

    abstract void setColor();

    abstract void setClothType();

    abstract Product createTheProduct();

    @BeforeClass
    public void setUp(){
      // there're partial overlaps of "setup" for pants and shirts
    }

    @Test
    public void doATest(){
        testSomethingWithProduct(product);
    }

    @AfterClass
    public void tearDown(){
      // there're partial overlaps of "tearDown" for pants and shirts
    }
}


public class TestBlueShirt extends BaseTestClass {

    @Override
    void setColor() {
        this.color = "blue";
    }

    @Override
    void setClothType() {
        this.type = "shirt";
    }

    @Override
    Product createTheProduct() {
       setColor();
       setClothType();
       // create this.product based on color and type...
    }
}

public class TestRedShirt extends BaseTestClass {}
public class TestBluePants extends BaseTestClass {}
public class TestRedPants extends BaseTestClass {}
...

You will find there's duplicated code when setting colors for the same type of cloth or when setting the type for the same color. I'm wondering how I can have a concrete class that can produce something like Class<T> (RedShirt, BlueShirt, RedPants, etc.), and based on Class<T>, I can directly implement @Test in the base class. So I can avoid code duplication as much as I can.

something like:

public abstract class BaseTestClass {

    protected Product product;

    abstract Product createTheProduct(Class<T> ...);

    @BeforeClass
    public void setUp(){
      setUpBasedOnProduct(Class<T> ...);

    }

    @Test
    public void doATest(){
        testSomethingWithProduct(product);
    }

    @AfterClass
    public void tearDown(){
        tearDownBasedOnProduct(Class<T> ...);
    }
}

import ...ClassGenerator

public class TestBlueShirt extends BaseTestClass {
    
    @Override
    createTheProduct(ClassGenerator.createClass("blue", "shirt"));
}

Thanks in advance!

Aucun commentaire:

Enregistrer un commentaire