Abstract Factory
基本上Abstract Factory就是在一個介面中定義了好幾個Factory Method,用此來產生一群型態不同但卻相關的物件。
使用時機
每一種所要產生的物件型別通常有著一種以上的實作方式。
不同實作方式的相關物件,無法放在一起使用,否則會造成系統錯誤或是傳達不清楚的語意。
from: 重新整理Abstract Factory Pattern
from: Abstract Factory Pattern Tutorial with Java Examples
Example
from: 抽象工廠模式(Abstract Factory Pattern)
Product interface
/**
* 跑車(抽象產品)
*/
public interface SportsCar {
/**
* 跑車比賽用
*/
public void competition();
}
/**
* 轎車(抽象產品)
*/
public interface Sedan {
/**
* 轎車工作用
*/
public void work();
}
Abstract factory
/**
* 抽象工廠
*
* 各家工廠需實作此介面,提供實際產品
*/
public interface AbstractFactory {
/**
* 製造一台轎車
*/
public Sedan buildSedan();
/**
* 製造一台跑車
*/
public SportsCar buildSportsCat();
}
Implement product & factory for BMW
/**
* BMW的跑車
*/
public class BmwSportsCat implements SportsCar {
@Override
public void competition() {
System.out.println("開BMW跑車比賽!");
}
}
/**
* BMW的轎車
*/
public class BmwSedan implements Sedan {
@Override
public void work() {
System.out.println("開BMW轎車上班");
}
}
/**
* BMW工廠:生產BMW的車
*/
public class BmwFactory implements AbstractFactory {
@Override
public Sedan buildSedan() {
return new BmwSedan();
}
@Override
public SportsCar buildSportsCat() {
return new BmwSportsCat();
}
}
Implement product & factory for Audi
/**
* Audi的跑車
*/
public class AudiSportsCat implements SportsCar {
@Override
public void competition() {
System.out.println("開Audi跑車比賽!");
}
}
/**
* Audi的轎車
*/
public class AudiSedan implements Sedan {
@Override
public void work() {
System.out.println("開Audi轎車上班");
}
}
/**
* Audi工廠:生產Audi的車
*/
public class AudiFactory implements AbstractFactory {
@Override
public Sedan buildSedan() {
return new AudiSedan();
}
@Override
public SportsCar buildSportsCat() {
return new AudiSportsCat();
}
}
Usage
public class Main {
public static void main(String[] args) {
// 可以選擇使用BMW或Audi的工廠
//AbstractFactory factory = new AudiFactory();
AbstractFactory factory = new BmwFactory();
// 不論使用哪個工廠,都可以使用相同的方式取得車子
Sedan sedan = factory.buildSedan();
SportsCar sportsCar = factory.buildSportsCat();
// 依賴於介面,所以可以使用相同的方式執行
sedan.work();
sportsCar.competition();
}
}