2017年2月17日 星期五

工廠方法模式

分成兩部分
1.工廠:寫一個介面,然後定義一些方法,最後由多個子類實作
2.產生工廠:寫一個抽象類別,使它可以產生1的產品,也是由子類別實作
使一個類別的實體化可以延遲到子類

※第二部分的產生工廠,如不寫抽象類別,然後將子類別的方法改成static,
因為變簡單了,所以就變成了簡單工廠模式,或者說靜態工廠模式


※1.工廠

public interface BreadFactory {
    void getBread();
    
    void getRaisin();
}
--------------------
public class FranceBread implements BreadFactory {
    @Override
    public void getBread() {
        System.out.print("法國麵包");
    }
    
    @Override
    public void getRaisin() {
        System.out.println("不用葡萄乾");
    }
}
--------------------
public class BoomBread implements BreadFactory {
    @Override
    public void getBread() {
        System.out.print("炸彈麵包");
    }
    
    @Override
    public void getRaisin() {
        System.out.println("取得葡萄乾");
    }
}




※2.產生工廠

public abstract class AbstractBreadFactory {
    public abstract <T extends BreadFactory> T generateBread(Class<T> clazz);
}
--------------------
public class MadeBreadFactory extends AbstractBreadFactory {
    @SuppressWarnings("unchecked")
    @Override
    public <T extends BreadFactory> T generateBread(Class<T> clazz) {
        BreadFactory breadFactory = null;
        try {
            breadFactory = (T) Class.forName(clazz.getName()).newInstance();
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return (T) breadFactory;
    }
}




※測試

AbstractBreadFactory factory = new MadeBreadFactory();
    
BreadFactory fb = factory.generateBread(FranceBread.class);
fb.getBread();
fb.getRaisin();
    
BreadFactory bb = factory.generateBread(BoomBread.class);
bb.getBread();
bb.getRaisin();

※結果:
法國麵包不用葡萄乾
炸彈麵包取得葡萄乾



※好處

只要知道類別名稱或字串(因Class.format也可接收包.類名的字串)即可,不用知道創建的過程,也就是低耦合

擴展性也很好,如再增加一個鳳梨麵包,只要增加一個類別即可,其他都不用改

使用JDBC時只要將Class.forName的字串改掉即可切換就是一例,但SQL當然要用標準的才行

沒有留言:

張貼留言