2017年2月20日 星期一

建造者、生成器(Builder)模式

模板模式如果順序想讓呼叫端自己決定,可加個List

有四個名詞需了解
Builder:為創建具體產品的具體建造者提供介面
ConcreteBuilder:建造具體產品
Director:呼叫 Builder 介面來創建產品物件
Product:具體產品(此例為模板模式的程式碼)

創建兩個抽象類別(builder類別和product類別),並讓子類實作,其中builder和product產生關聯
最後 Director 放 builder


public abstract class AbstractTemplate {
    public enum EnumMethods {
        m1, m2, m3;
    }
    
    private List<EnumMethods> list = new ArrayList<>();
    
    public void setList(List<EnumMethods> list) {
        this.list = list;
    }
    
    protected abstract void method1();
    protected abstract void method2();
    protected abstract void method3();
    
    public void builderMethod() {
        for (EnumMethods em : list) {
            switch (em) {
            case m1:
                this.method1();
                break;
            case m2:
                this.method2();
                break;
            case m3:
                this.method3();
                break;
            }
        }
    }
}
--------------------
public class Concrete1 extends AbstractTemplate {
    @Override
    protected void method1() {
        System.out.println("Concrete1 m1");
    }
    
    @Override
    protected void method2() {
        System.out.println("Concrete1 m2");
    }
    
    @Override
    protected void method3() {
        System.out.println("Concrete1 m3");
    }
}
--------------------
public class Concrete2 extends AbstractTemplate {
    @Override
    protected void method1() {
        System.out.println("Concrete2 m1");
    }
    
    @Override
    protected void method2() {
        System.out.println("Concrete2 m2");
    }
    
    @Override
    protected void method3() {
        System.out.println("Concrete2 m3");
    }
}




※測試

List<EnumMethods> list1 = new ArrayList<>();
list1.add(EnumMethods.m2);
list1.add(EnumMethods.m1);
list1.add(EnumMethods.m3);
    
List<EnumMethods> list2 = new ArrayList<>();
list2.add(EnumMethods.m3);
list2.add(EnumMethods.m2);
list2.add(EnumMethods.m1);
    
AbstractTemplate c1 = new Concrete1();
c1.setList(list1);
c1.builderMethod();
System.out.println();
AbstractTemplate c2 = new Concrete2();
c2.setList(list2);
c2.builderMethod();

※結果:
Concrete1 m2
Concrete1 m1
Concrete1 m3

Concrete2 m3
Concrete2 m2
Concrete2 m1



加上Builder


public abstract class AbstractBuilder {
    public abstract void setList(List<EnumMethods> list);
    public abstract AbstractTemplate getAbstractTemplate();
}
--------------------
public class Concrete1Builder extends AbstractBuilder {
    private Concrete1 c1 = new Concrete1();
    
    @Override
    public void setList(List<EnumMethods> list) {
        c1.setList(list);
    }
    
    @Override
    public AbstractTemplate getAbstractTemplate() {
        return c1;
    }
}
--------------------
public class Concrete2Builder extends AbstractBuilder {
    private Concrete2 c2 = new Concrete2();
    
    @Override
    public void setList(List<EnumMethods> list) {
        c2.setList(list);
    }
    
    @Override
    public AbstractTemplate getAbstractTemplate() {
        return c2;
    }
}




※測試

List<EnumMethods> list1 = new ArrayList<>();
list1.add(EnumMethods.m2);
list1.add(EnumMethods.m1);
list1.add(EnumMethods.m3);
    
List<EnumMethods> list2 = new ArrayList<>();
list2.add(EnumMethods.m3);
list2.add(EnumMethods.m2);
list2.add(EnumMethods.m1);
    
AbstractBuilder c1 = new Concrete1Builder();
c1.setList(list1);
AbstractTemplate at1 = c1.getAbstractTemplate();
at1.builderMethod();
System.out.println();
AbstractBuilder c2 = new Concrete1Builder();
c2.setList(list2);
AbstractTemplate at2 = c2.getAbstractTemplate();
at2.builderMethod();

※結果一樣


加上Director


public class Director {
    private List<EnumMethods> list1 = new ArrayList<>();
    private List<EnumMethods> list2 = new ArrayList<>();
    Concrete1Builder c1 = new Concrete1Builder();
    Concrete2Builder c2 = new Concrete2Builder();
    
    public void setList1(List<EnumMethods> list1) {
        this.list1 = list1;
    }
    
    public void setList2(List<EnumMethods> list2) {
        this.list2 = list2;
    }
    
    public Concrete1 getConcrete1() {
        c1.setList(list1);
        return (Concrete1) c1.getAbstractTemplate();
    }
    
    public Concrete2 getConcrete2() {
        c2.setList(list2);
        return (Concrete2) c2.getAbstractTemplate();
    }
}




※測試

List<EnumMethods> list1 = new ArrayList<>();
list1.add(EnumMethods.m2);
list1.add(EnumMethods.m1);
list1.add(EnumMethods.m3);
    
List<EnumMethods> list2 = new ArrayList<>();
list2.add(EnumMethods.m3);
list2.add(EnumMethods.m2);
list2.add(EnumMethods.m1);
    
Director dir = new Director();
dir.setList1(list1);
dir.setList2(list2);
    
dir.getConcrete1().builderMethod();
System.out.println();
dir.getConcrete2().builderMethod();

※結果一樣

沒有留言:

張貼留言