天天看點

設計模式中的建立類模式設計模式中的建立類模式工廠方法模式 VS 建造者模式抽象工廠模式 VS 建造者模式

設計模式中的建立類模式

建立類模式包括工廠方法模式、建造者模式、抽象工廠模式、單例模式和原型模式。

  • 單例模式:要保持在記憶體中隻有一個對象。
  • 原型模式:要求通過複制的方式産生一個新的對象。實作Cloneable接口,并覆寫和重寫clone()方法。克隆。
  • 工廠方法模式:注重的是整體對象的建立方法,用一個類封裝特定産品的執行個體化,即把new進行封裝。
  • 建造者模式:注重的是部件建構的過程。先使用一個類對産品進行組裝,然後再使用導演類對其封裝。
  • 抽象工廠模式:不需要關心建構過程,隻關心什麼産品由什麼工廠生産。

工廠方法模式 VS 建造者模式

差別

(1)意圖不同:

  • 工廠方法模式,關注的是一個産品整體;
  • 建造者模式,關注的是産品各個部件的産生以及裝配順序。

(2)産品的複雜度不同:

  • 工廠方法模式建立的産品一般都是單一性質産品,都是一個模樣;
  • 建造者模式建立的是一個複合産品,它由各個部件複合而成,部件不同産品對象不同。

工廠方法模式的對象粒度比較粗,建造者模式的産品對象粒度比較細。

例如

如要制造一個超人,如果使用工廠方法模式,直接産生出來的就是一個力大無窮、能夠飛翔、内褲外穿的超人;而如果使用建造者模式,則需要組裝手、頭、腳、軀幹等部分,然後再把内褲外穿,才會産生一個超人。

(1)工廠方法模式建造超人

設計模式中的建立類模式設計模式中的建立類模式工廠方法模式 VS 建造者模式抽象工廠模式 VS 建造者模式
public interface ISuperMan { 
    //每個超人都有特殊技能 
    public void specialTalent(); 
}
           
public class AdultSuperMan implements ISuperMan { //成年超人
    public void specialTalent() { 
        System.out.println("超人力大無窮"); 
    }
}
           
public class ChildSuperMan implements ISuperMan { //未成年超人 
    public void specialTalent() { 
        System.out.println("小超人的能力是刀槍不入、快速運動"); 
    }
}
           
public class SuperManFactory { 
    //定義一個生産超人的工廠 
    public static ISuperMan createSuperMan(String type){ 
        //根據輸入參數産生不同的超人 
        if(type.equalsIgnoreCase("adult")){ 
            return new AdultSuperMan(); 
        }else if(type.equalsIgnoreCase("child")){ 
            return new ChildSuperMan(); 
        }else{ 
            return null; 
        } 
    } 
} 
           
public class Client { 
    public static void main(String[] args) { 
        //生産一個成年超人 
        ISuperMan adultSuperMan = SuperManFactory.createSuperMan("adult"); 
        //展示一下超人的技能 
        adultSuperMan.specialTalent(); 
    } 
} 
           

注意:通過工廠方法模式生産出對象,然後由用戶端進行對象的其他操作,但是并不代表所有生産出的對象都必須具有相同的狀态和行為,它是由産品所決定。

(2)建造者模式建造超人

設計模式中的建立類模式設計模式中的建立類模式工廠方法模式 VS 建造者模式抽象工廠模式 VS 建造者模式
public class SuperMan { 
    //超人的軀體 
    private String body; 
    //超人的特殊技能 
    private String specialTalent; 
    //超人的标志 
    private String specialSymbol; 
    public String getBody() { 
        return body; 
    }
    public void setBody(String body) { 
        this.body = body; 
    }
    public String getSpecialTalent() { 
        return specialTalent; 
    }
    public void setSpecialTalent(String specialTalent) { 
        this.specialTalent = specialTalent; 
    }
    public String getSpecialSymbol() { 
        return specialSymbol; 
    }
    public void setSpecialSymbol(String specialSymbol) { 
        this.specialSymbol = specialSymbol; 
    }
} 
           
public abstract class Builder { 
    //定義一個超人的應用 
    protected final SuperMan superMan = new SuperMan(); 
    //建構出超人的軀體 
    public void setBody(String body){ 
        this.superMan.setBody(body); 
    }
    //建構出超人的特殊技能 
    public void setSpecialTalent(String st){ 
        this.superMan.setSpecialTalent(st); 
    }
    //建構出超人的特殊标記 
    public void setSpecialSymbol(String ss){ 
        this.superMan.setSpecialSymbol(ss); 
    }
    //建構出一個完整的超人 
    public abstract SuperMan getSuperMan(); 
} 
           
public class AdultSuperManBuilder extends Builder { 
    @Override 
    public SuperMan getSuperMan() { 
        super.setBody("強壯的軀體"); 
        super.setSpecialTalent("會飛行"); 
        super.setSpecialSymbol("胸前帶S标記"); 
        return super.superMan; 
    } 
}
           
public class ChildSuperManBuilder extends Builder { 
    @Override 
    public SuperMan getSuperMan() { 
        super.setBody("強壯的軀體"); 
        super.setSpecialTalent("刀槍不入"); 
        super.setSpecialSymbol("胸前帶小S标記"); 
        return super.superMan; 
    } 
} 
           
public class Director { 
    //兩個建造者的應用 
    private static Builder adultBuilder = new AdultSuperManBuilder(); 
    //未成年超人的建造者 
    private static Builder childBuilder = new ChildSuperManBuilder(); 
    //建造一個成年、會飛行的超人 
    public static SuperMan getAdultSuperMan(){ 
        return adultBuilder.getSuperMan(); 
    }
    //建造一個未成年、刀槍不入的超人 
    public static SuperMan getChildSuperMan(){ 
        return childBuilder.getSuperMan(); 
    } 
} 
           
public class Client { 
    public static void main(String[] args) { 
        //建造一個成年超人 
        SuperMan adultSuperMan = Director.getAdultSuperMan(); 
        //展示一下超人的資訊 
        adultSuperMan.getSpecialTalent(); 
    } 
} 
           

建造者必須關注超人的各個部件,而工廠方法模式則隻關注超人的整體,這就是兩者的差別。

抽象工廠模式 VS 建造者模式

差別

  • 如果希望屏蔽對象的建立過程,隻提供一個封裝良好的對象,則可以選擇抽象工廠方法模式。
  • 而建造者模式可以用在構件的裝配方面,如通過裝配不同的元件或者相同元件的不同順序,可以産生出一個新的對象,它可以産生一個非常靈活的架構,友善地擴充和維護系統。

例如

現代化的汽車工廠能夠批量生産汽車。不同的工廠生産不同的汽車,寶馬工廠生産寶馬牌子的車,奔馳工廠生産奔馳牌子的車。車不僅具有不同品牌,還有不同的用途分類,如商務車Van,運動型車SUV等,我們按照兩種設計模式分别實作車輛的生産過程。

(1)抽象工廠模式生産車輛

設計模式中的建立類模式設計模式中的建立類模式工廠方法模式 VS 建造者模式抽象工廠模式 VS 建造者模式
public interface ICar { 
    //汽車的生産商,也就是牌子 
    public String getBand(); 
    //汽車的型号 
    public String getModel(); 
}
           
public abstract class AbsBMW implements ICar { 
    private final static String BMW_BAND = "寶馬汽車"; 
    //寶馬車 
    public String getBand() { 
        return BMW_BAND; 
    }
    //型号由具體的實作類實作 
    public abstract String getModel(); 
} 
           
public class BMWVan extends AbsBMW { 
    private final static String SEVENT_SEARIES = "7系列車型商務車"; 
    public String getModel() { 
        return SEVENT_SEARIES; 
    } 
} 


public class BMWSuv extends AbsBMW { 
    private final static String X_SEARIES = "X系列車型SUV"; 
    public String getModel() { 
        return X_SEARIES; 
    } 
} 
           
public abstract class AbsBenz implements ICar { 
    private final static String BENZ_BAND = "奔馳汽車"; 
    public String getBand() { 
        return BENZ_BAND; 
    }
    //具體型号由實作類完成
    public abstract String getModel(); 
}
           
public class BenzVan extends AbsBenz { 
    private final static String R_SERIES = "R系列商務車"; 
    public String getModel() { 
        return R_SERIES; 
    } 
}

public class BenzSuv extends AbsBenz { 
    private final static String G_SERIES = "G系列SUV"; 
    public String getModel() { 
        return G_SERIES; 
    } 
} 
           
public interface CarFactory { 
    //生産SUV 
    public ICar createSuv(); 
    //生産商務車 
    public ICar createVan(); 
}
           
public class BMWFactory implements CarFactory { 
    //生産SUV 
    public ICar createSuv() { 
        return new BMWSuv();
    }
    //生産商務車 
    public ICar createVan(){ 
        return new BMWVan(); 
    } 
} 

public class BenzFactory implements CarFactory { 
    //生産SUV 
    public ICar createSuv() { 
        return new BenzSuv(); 
    }
    //生産商務車 
    public ICar createVan(){ 
        return new BenzVan(); 
    } 
} 
           
public class Client { 
    public static void main(String[] args) { 
        //要求生産一輛奔馳SUV 
        System.out.println("===要求生産一輛奔馳SUV==="); 
        //首先找到生産奔馳車的工廠 
        System.out.println("A、找到奔馳車工廠"); 
        CarFactory carFactory= new BenzFactory(); 
        //開始生産奔馳SUV 
        System.out.println("B、開始生産奔馳SUV"); 
        ICar benzSuv = carFactory.createSuv(); 
        //生産完畢,展示一下車輛資訊 
        System.out.println("C、生産出的汽車如下:"); 
        System.out.println("汽車品牌:"+benzSuv.getBand()); 
        System.out.println("汽車型号:" + benzSuv.getModel()); 
    } 
} 
           

(2)建造者模式生産車輛

建造者模式需要把車輛進行拆分,拆分成引擎和車輪兩部分,然後由建造者根據設計圖紙制造車。它注重的是對零件的裝配、組合、封裝,從一個細微構件裝配角度看待一個對象。

設計模式中的建立類模式設計模式中的建立類模式工廠方法模式 VS 建造者模式抽象工廠模式 VS 建造者模式
public interface ICar { 
    //汽車車輪 
    public String getWheel(); 
    //汽車引擎 
    public String getEngine(); 
}
           
public class Car implements ICar { 
    //汽車引擎 
    private String engine; 
    //汽車車輪 
    private String wheel; 
    //一次性傳遞汽車需要的資訊 
    public Car(String _engine,String _wheel){ 
        this.engine = _engine; 
        this.wheel = _wheel; 
    }
    public String getEngine() { 
        return engine;
    }
    public String getWheel() { 
        return wheel; 
    }
    public String toString(){ 
        return "車的輪子是:" + wheel + "\n車的引擎是:" + engine; 
    } 
} 
           
public abstract class CarBuilder { 
    //待建造的汽車 
    private ICar car; 
    //設計藍圖 
    private Blueprint bp; 
    public Car buildCar(){ 
        //按照順序生産一輛車 
        return new Car(buildEngine(),buildWheel()); 
    }
    //接收一份設計藍圖 
    public void receiveBlueprint(Blueprint _bp){ 
        this.bp = _bp; 
    }
    //檢視藍圖,隻有真正的建造者才可以檢視藍圖 
    protected Blueprint getBlueprint(){ 
        return bp; 
    }
    //建造車輪 
    protected abstract String buildWheel(); 
    //建造引擎 
    protected abstract String buildEngine(); 
} 
           
public class Blueprint { 
    //車輪的要求 
    private String wheel; 
    //引擎的要求 
    private String engine; 
    public String getWheel() { 
        return wheel; 
    }
    public void setWheel(String wheel) { 
        this.wheel = wheel; 
    }
    public String getEngine() { 
        return engine; 
    }
    public void setEngine(String engine) { 
        this.engine = engine; 
    } 
} 
           

這和一個具體的産品Car類是不一樣的,它是一個藍圖,有一個藍圖可以設計出非常多的産品,如有一個R系統的奔馳商務車設計藍圖,我們就可以生産出一系列的奔馳車。它指導我們的産品生産,而不是一個具體的産品。

public class BMWBuilder extends CarBuilder { 
    public String buildEngine() { 
        return super.getBlueprint().getEngine(); 
    }
    public String buildWheel() { 
        return super.getBlueprint().getWheel(); 
    } 
} 

public class BenzBuilder extends CarBuilder { 
    public String buildEngine() { 
        return super.getBlueprint().getEngine(); 
    }
    public String buildWheel() { 
        return super.getBlueprint().getWheel(); 
    }
}
           
public class Director { 
    //聲明對建造者的引用 
    private CarBuilder benzBuilder = new BenzBuilder(); 
    private CarBuilder bmwBuilder = new BMWBuilder(); 
    //生産奔馳SUV 
    public ICar createBenzSuv(){ 
        //制造出汽車 
        return createCar(benzBuilder, "benz的引擎", "benz的輪胎"); 
    }
    //生産出一輛寶馬商務車 
    public ICar createBMWVan(){ 
        return createCar(benzBuilder, "BMW的引擎", "BMW的輪胎"); 
    }
    //生産出一個混合車型 
    public ICar createComplexCar(){ 
        return createCar(bmwBuilder, "BMW的引擎", "benz的輪胎"); 
    }
    //生産車輛 
    private ICar createCar(CarBuilder _carBuilder,String engine,String wheel){ 
        //導演懷揣藍圖 
        Blueprint bp = new Blueprint(); 
        bp.setEngine(engine); 
        bp.setWheel(wheel); 
        System.out.println("獲得生産藍圖"); 
        _carBuilder.receiveBlueprint(bp); 
        return _carBuilder.buildCar(); 
    } 
} 
           
public class Client { 
    public static void main(String[] args) { 
        //定義出導演類 
        Director director =new Director(); 
        //給我一輛奔馳車SUV 
        System.out.println("===制造一輛奔馳SUV===");
        ICar benzSuv = director.createBenzSuv(); 
        System.out.println(benzSuv); 
        //給我一輛寶馬商務車 
        System.out.println("\n===制造一輛寶馬商務車==="); 
        ICar bmwVan = director.createBMWVan(); 
        System.out.println(bmwVan); 
        //給我一輛混合車型 
        System.out.println("\n===制造一輛混合車==="); 
        ICar complexCar = director.createComplexCar(); 
        System.out.println(complexCar); 
    } 
} 
           

繼續閱讀