跳转至

模板模式

时间:2017-08-07 10:58:03 参考:

  1. 《设计模式之禅(第二版)》-- 秦小波
  2. 《Java编程思想(第四版)》-- Bruce Eckel

模板方法 (Template Method Pattern)#

1
Define the skeleton of an algorithm in an operation,deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's.

定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

通俗描述#

把相同的方法的实现放在父类中,这样子类通过继承可以拥有相同的方法,不需要重写相同的方法的实现。
把不相同方法定义为抽象的方法,在子类中根据不同的应用场景具体实现。

代码#

基础类#

Pet

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public abstract class Pet {
    protected String name;
    public Pet() {}
    public Pet(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Pet{" +
                "name='" + name + '\'' +
                '}';
    }
}

Cat

1
2
3
4
5
6
public class Cat extends Pet {
    public Cat() {super();}
    public Cat(String name) {
        super(name);
    }
}

Dog

1
2
3
4
5
6
public class Dog extends Pet {
    public Dog() {super();}
    public Dog(String name) {
        super(name);
    }
}

Manx

1
2
3
4
5
6
public class Manx extends Cat{
    public Manx() {super();}
    public Manx(String name) {
        super(name);
    }
}

模板类#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public abstract class PetCreator {

    private Random random = new Random(47);

    // 由子类具体实现
    public abstract List<Class<? extends Pet>> types();

    public Pet randomPet() {
        int index = random.nextInt(types().size());

        try {
            return types().get(index).newInstance();
        }
        catch (InstantiationException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
        catch (IllegalAccessException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public Pet[] createArray(int size) {
        Pet[] pets = new Pet[size];
        for (int i = 0; i < size; i++) {
            pets[i] = randomPet();
        }
        return pets;
    }

    public List<Pet> list(int size) {
        ArrayList<Pet> pets = new ArrayList<>();
        Collections.addAll(pets, createArray(size));
        return pets;
    }
}

模板类实现#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class ForNameCreator extends PetCreator {

    private static List<Class<? extends Pet>> types = new ArrayList<>();

    private static String[] typeNames = {
            "com.sun.xiaotian.learing.thinking_in_java.type_.pet.Dog",
            "com.sun.xiaotian.learing.thinking_in_java.type_.pet.Cat",
            "com.sun.xiaotian.learing.thinking_in_java.type_.pet.Manx"
    };

    private static void loader() {
        try {
            for (String typeName : typeNames) {
                types.add((Class<? extends Pet>) Class.forName(typeName));
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    static {
        loader();
    }

    @Override
    public List<Class<? extends Pet>> types() {
        return types;
    }
}

测试类#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class TestPetCreator {

    public static void main(String[] args) {
        PetCreator forNameCreator = new ForNameCreator();

        for (int i = 0; i < 20; i++) {
            Pet pet = forNameCreator.randomPet();

            if (pet instanceof Cat) {
                System.out.print("Cat ");
            }

            if(pet instanceof Dog) {
                System.out.print("Dog ");
            }

            if(pet instanceof Manx) {
                System.out.print("Manx ");
            }
            System.out.println();
        }

    }
}

输出结果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
Cat Manx 
Cat Manx 
Cat 
Cat Manx 
Cat 
Cat Manx 
Cat 
Cat Manx 
Dog 
Cat 
Dog 
Dog 
Dog 
Cat 
Cat Manx 
Cat 
Cat 
Cat 
Cat Manx 
Cat