工廠模式:
what(是什麼)
屬於創建對象模式,它提供了一種創建對象的最佳方式.
why(爲什麼用它)
在工廠模式中我們牀架 對象時不會對客戶端暴露創建
邏輯,並且是通過使用一個共同的接口來指向新創建的對象.
應用實例:
1 當需要一輛汽車時,可以直接從工廠裏面提貨,而不用去管
這輛汽車時怎麼來的,以及這個汽車的具體實現.
2 Hibernate換數據庫只需要換方言和驅動就可以了.
優點:1 一個調用者想要創建一個對象,只要知道其名稱就可以了.
2 擴展性高,如果想增加一個產品,只要擴展一個工廠類就可以了.
3 屏蔽產品的具體實現,調用者只關心產品的接口
缺點:1 每次增加一個產品時,都需要增加一個具體類和對象實現工廠,使得系統中類的個數成倍增加,在一定程度上增加了系統的複雜度,同時也增加了系統具體類的依賴。這並不是什麼好事。
注意事項:作爲一種創建類模式,在任何需要生成複雜對象的地方,都可以使用工廠方法模式。有一點需要注意的地方就是複雜對象適合使用工廠模式,而簡單對象,特別是只需要通過 new 就可以完成創建的對象,無需使用工廠模式。如果使用工廠模式,就需要引入一個工廠類,會增加系統的複雜度。
how(怎麼用它)
工廠模式可以分爲三類:
1)簡單工廠模式(Simple Factory)
建立一個工廠(一個函數或一個類方法)來製造新的對象。
public class BMW320 {
public BMW320(){
System.out.println("製造-->BMW320");
}
}
public class BMW523 {
public BMW523(){
System.out.println("製造-->BMW523");
}
}
public class Customer {
public static void main(String[] args) {
BMW320 bmw320 = new BMW320();
BMW523 bmw523 = new BMW523();
}
}
客戶需要知道怎麼去創建一款車,客戶和車就緊密耦合在一起了.爲了降低耦合,就出現了工廠類,把創建寶馬的操作細節都放到了工廠裏面去,客戶直接使用工廠的創建工廠方法,傳入想要的寶馬車型號就行了,而不必去知道創建的細節.這就是工業革命了:簡單工廠模式
產品類:
abstract class BMW {
public BMW(){
}
}
public class BMW320 extends BMW {
public BMW320() {
System.out.println("製造-->BMW320");
}
}
public class BMW523 extends BMW{
public BMW523(){
System.out.println("製造-->BMW523");
}
}
工廠類:
public class Factory {
public BMW createBMW(int type) {
switch (type) {
case 320:
return new BMW320();
case 523:
return new BMW523();
default:
break;
}
return null;
}
}
客戶類:
public class Customer {
public static void main(String[] args) {
Factory factory = new Factory();
BMW bmw320 = factory.createBMW(320);
BMW bmw523 = factory.createBMW(523);
}
}
2)工廠方法模式(Factory Method)
廠方法模式使用繼承自抽象工廠角色的多個子類來代替簡單工廠模式中的“上帝類”。正如上面所說,這樣便分擔了對象承受的壓力;而且這樣使得結構變得靈活 起來——當有新的產品產生時,只要按照抽象產品角色、抽象工廠角色提供的合同來生成,那麼就可以被客戶使用,而不必去修改任何已有 的代碼。可以看出工廠角色的結構也是符合開閉原則的!
產品類:
abstract class BMW {
public BMW(){
}
}
public class BMW320 extends BMW {
public BMW320() {
System.out.println("製造-->BMW320");
}
}
public class BMW523 extends BMW{
public BMW523(){
System.out.println("製造-->BMW523");
}
}
創建工廠類:
interface FactoryBMW {
BMW createBMW();
}
public class FactoryBMW320 implements FactoryBMW{
@Override
public BMW320 createBMW() {
return new BMW320();
}
}
public class FactoryBMW523 implements FactoryBMW {
@Override
public BMW523 createBMW() {
return new BMW523();
}
}
客戶類:
public class Customer {
public static void main(String[] args) {
FactoryBMW320 factoryBMW320 = new FactoryBMW320();
BMW320 bmw320 = factoryBMW320.createBMW();
FactoryBMW523 factoryBMW523 = new FactoryBMW523();
BMW523 bmw523 = factoryBMW523.createBMW();
}
}
3)抽象工廠模式(Abstract Factory)
隨着客戶的要求越來越高,寶馬車需要不同配置的空調和發動機等配件。於是這個工廠開始生產空調和發動機,用來組裝汽車。這時候工廠有兩個系列的產品:空調和發動機。寶馬320系列配置A型號空調和A型號發動機,寶馬230系列配置B型號空調和B型號發動機。
概念:
抽象工廠模式是工廠方法模式的升級版本,他用來創建一組相關或者相互依賴的對象。比如寶馬320系列使用空調型號A和發動機型號A,而寶馬230系列使用空調型號B和發動機型號B,那麼使用抽象工廠模式,在爲320系列生產相關配件時,就無需制定配件的型號,它會自動根據車型生產對應的配件型號A。
當每個抽象產品都有多於一個的具體子類的時候(空調有型號A和B兩種,發動機也有型號A和B兩種),工廠角色怎麼知道實例化哪一個子類呢?比如每個抽象產品角色都有兩個具體產品(產品空調有兩個具體產品空調A和空調B)。抽象工廠模式提供兩個具體工廠角色(寶馬320系列工廠和寶馬230系列工廠),分別對應於這兩個具體產品角色,每一個具體工廠角色只負責某一個產品角色的實例化。每一個具體工廠類只負責創建抽象產品的某一個具體子類的實例。
產品類:
public interface Engine {
}
public class EngineA extends Engine{
public EngineA(){
System.out.println("製造-->EngineA");
}
}
public class EngineBextends Engine{
public EngineB(){
System.out.println("製造-->EngineB");
}
}
//空調以及型號
public interface Aircondition {
}
public class AirconditionA extends Aircondition{
public AirconditionA(){
System.out.println("製造-->AirconditionA");
}
}
public class AirconditionB extends Aircondition{
public AirconditionB(){
System.out.println("製造-->AirconditionB");
}
}
創建工廠類:
//創建工廠的接口
public interface AbstractFactory {
//製造發動機
public Engine createEngine();
//製造空調
public Aircondition createAircondition();
}
//爲寶馬320系列生產配件
public class FactoryBMW320 implements AbstractFactory{
@Override
public Engine createEngine() {
return new EngineA();
}
@Override
public Aircondition createAircondition() {
return new AirconditionA();
}
}
//寶馬523系列
public class FactoryBMW523 implements AbstractFactory {
@Override
public Engine createEngine() {
return new EngineB();
}
@Override
public Aircondition createAircondition() {
return new AirconditionB();
}
}
客戶:
public class Customer {
public static void main(String[] args){
//生產寶馬320系列配件
FactoryBMW320 factoryBMW320 = new FactoryBMW320();
factoryBMW320.createEngine();
factoryBMW320.createAircondition();
//生產寶馬523系列配件
FactoryBMW523 factoryBMW523 = new FactoryBMW523();
factoryBMW320.createEngine();
factoryBMW320.createAircondition();
}
}
總結:
無論是簡單工廠模式,工廠方法模式,還是抽象工廠模式,他們都屬於工廠模式,在形式和特點上也是極爲相似的,他們的最終目的都是爲了解耦。在使用時,我們不必去在意這個模式到底工廠方法模式還是抽象工廠模式,因爲他們之間的演變常常是令人琢磨不透的。經常你會發現,明明使用的工廠方法模式,當新需求來臨,稍加修改,加入了一個新方法後,由於類中的產品構成了不同等級結構中的產品族,它就變成抽象工廠模式了;而對於抽象工廠模式,當減少一個方法使的提供的產品不再構成產品族之後,它就演變成了工廠方法模式。
所以,在使用工廠模式時,只需要關心降低耦合度的目的是否達到了。