mave工程中的一个类调用另一个聚合工程的一个类_谈谈设计模式:建造者模式在jdk中的体现,它和工厂模式区别?...
背景
建造模式(Builder模式)
假如有一個(gè)需求:蓋房子,蓋房子過(guò)程是一致的:打樁、砌墻、封頂。但是房子是各式各樣的,最后蓋出來(lái)的房子可能是高樓或別墅。
根據(jù)直接的思路,不用設(shè)計(jì)模式思想,我們也許會(huì):
寫一個(gè) CommonHouse 抽象類,然后里面規(guī)定了打樁、砌墻、封頂三個(gè)方法;
讓不同房子繼承這個(gè)類;
最后調(diào)用的時(shí)候調(diào)用分別的方法即可。
在繼承抽象類、子類區(qū)分這一塊,思想沒(méi)有問(wèn)題,問(wèn)題出現(xiàn)這些類本身。
缺點(diǎn):
過(guò)于簡(jiǎn)單,將產(chǎn)品(房子)和創(chuàng)建產(chǎn)品(房子建造流程)封裝在了一起,耦合性增強(qiáng)了。(可以理解為,面向?qū)ο蟮乃枷肜?#xff0c;房子雖然是一個(gè)類,擁有自己的方法,但是房子不應(yīng)該擁有建造自己的方法)
解決方法:
解耦 - > 建造者模式。
一、建造者模式
建造者模式(Builder Pattern)又叫生成器模式,是一種對(duì)象構(gòu)建模式(創(chuàng)建型),可以將復(fù)雜對(duì)象的建造過(guò)程抽象出來(lái)(抽象類),使這個(gè)抽象過(guò)程的不同實(shí)現(xiàn)方法能構(gòu)造出不同表現(xiàn)(屬性)的對(duì)象。
建造模式允許用戶只通過(guò)指定復(fù)雜對(duì)象的類型和內(nèi)容就可以構(gòu)建他們,用戶不需要知道內(nèi)部的具體構(gòu)建細(xì)節(jié)。
建造者模式的四個(gè)角色:
Product產(chǎn)品:一個(gè)具體產(chǎn)品對(duì)象;
Builder(抽象建造者):創(chuàng)建Product對(duì)象指定的 接口或者抽象類;
ConcreteBuilder具體建造者:實(shí)現(xiàn)接口,構(gòu)建和裝配各個(gè)部件;
Director指揮者:構(gòu)建一個(gè)使用Builder接口的對(duì)象,主要用于創(chuàng)建一個(gè)復(fù)雜度對(duì)象,有兩個(gè)作用:一是隔離客戶與對(duì)象的生產(chǎn)過(guò)程,二是負(fù)責(zé)控制產(chǎn)品對(duì)象的生產(chǎn)過(guò)程。
他們之間的關(guān)系,我們用類圖來(lái)解釋:
Directer里面聚合一個(gè)Builder實(shí)際上使用的是他的實(shí)現(xiàn)類ConcreteBuilder;
ConcreteBuilder可以有很多,就是所謂的不同的房子的建造者。
因?yàn)間etRusult是一樣的,所以暫時(shí)不用接口,用抽象類實(shí)現(xiàn)Builder,代碼如下:
/*
產(chǎn)品,對(duì)應(yīng)product*/
public class House {
private String base;
private String wall;
private String roof;
//對(duì)應(yīng)getset方法
}
/*
抽象的建造者,對(duì)應(yīng)Builder*/
public abstract class HouseBuilder {
protected House house = new House();
//寫好流程的各個(gè)方法,但不約束具體執(zhí)行
public abstract void buildBasic();
public abstract void buildWalls();
public abstract void buildRoof();
//建造方法,返回建造結(jié)果
public House buildHouse(){
return house;
}
}
/*
普通房子制造流程,繼承抽象類可以看到,制造流程在這里,而House類擁有房子的屬性,他們是分開(kāi)的
應(yīng)是對(duì)House的操作,這里省略
*/
public class CommonHouse extends HouseBuilder{
@Override
public void buildBasic() {
System.out.println("普通房子:建造地基。。。");
}
@Override
public void buildWalls() {
System.out.println("普通房子:砌墻。。。");
}
@Override
public void buildRoof() {
System.out.println("普通房子:蓋屋頂。。。");
}
}
/*
另一個(gè)實(shí)現(xiàn)類,本來(lái)應(yīng)是對(duì)House的操作,這里省略*/
public class HighHouse extends HouseBuilder {
@Override
public void buildBasic() {
System.out.println("高樓:建造地基。。。");
}
@Override
public void buildWalls() {
System.out.println("高樓:砌墻。。。");
}
@Override
public void buildRoof() {
System.out.println("高樓:蓋屋頂。。。");
}
}
/*
Director,聚合建造者HouseBuilder同時(shí)決定制作流程,最后調(diào)用建造者的buildHouse方法返回
*/
public class Director {
HouseBuilder houseBuilder = null;
//通過(guò)構(gòu)造器聚合
public Director(HouseBuilder houseBuilder) {
this.houseBuilder = houseBuilder;
}
//通過(guò)setter方法聚合
public void setHouseBuilder(HouseBuilder houseBuilder) {
this.houseBuilder = houseBuilder;
}
//指揮具體建造流程,先后順序不由Builder決定
public House constructHouse(){
houseBuilder.buildBasic();
houseBuilder.buildWalls();
houseBuilder.buildRoof();
return houseBuilder.buildHouse();
}
}
/*
客戶端*/
public class Client {
public static void main(String[] args) {
//new房子
CommonHouse commonHouse = new CommonHouse();
//new指揮者
Director director = new Director(commonHouse);
//完成蓋房
House house = director.constructHouse();
//重置建造者
HighHouse highHouse = new HighHouse();
director.setHouseBuilder(highHouse);
House house1 = director.constructHouse();
}
}
上面代碼總結(jié)起來(lái):一是要把房子歸為房子,有屬性就夠了,建造歸建造,相當(dāng)于是建筑工人,和房子兩個(gè)對(duì)象分開(kāi),那么Director相當(dāng)于包工頭,對(duì)于不同的House要指揮不一樣的Builder群體。
二、建造者模式在JDK中的應(yīng)用
java.lang.StringBuilder類,也就是常用的可變字符串類,用到的就是建造者模式。以其中的常用方法 append 方法為例看源碼。
2.1 Appendable 接口
定義了多個(gè) append 方法(抽象方法),即 Appendable 就是我們的抽象建造者Builder 。
2.2 具體的實(shí)現(xiàn)類 AbstractStringBuilder
雖然也是一個(gè)抽象類,但是也已經(jīng)實(shí)現(xiàn)了 Append able 接口的方法,所以其實(shí)相當(dāng)于是具體的建造者ConcreteBuilder了;
2.3 StringBuilder,繼承了AbstractStringBuilder
但是他重寫 append 方法的方式只是調(diào)用了父類方法,所以應(yīng)該說(shuō),StringBuilder既充當(dāng)了Director,又是一個(gè)ConcreteBuilder.
三、注意事項(xiàng)
客戶端不必知道產(chǎn)品呢內(nèi)部組成的細(xì)節(jié),將產(chǎn)品本身和產(chǎn)品的創(chuàng)建過(guò)程解耦,使得相同的創(chuàng)建過(guò)程可以創(chuàng)建不同的產(chǎn)品;
每一個(gè)具體的建造者都是相對(duì)獨(dú)立的,和其他的建造者無(wú)關(guān),因此可以方便替換具體建造者或者增加新的具體建造者,用戶使用不同的具體建造者就能得到不同產(chǎn)品;
可以更加精細(xì)的控制創(chuàng)建過(guò)程;
增加新的具體建造者無(wú)需修改原有代碼,指揮者針對(duì)抽象建造者編程;
建造者模式創(chuàng)建的產(chǎn)品,一定是共同點(diǎn)比較多,組成部分相似,如果產(chǎn)品之間的差異性很大,那么就不適合使用建造者模式,因此其適用范圍受到一定的限制。
建造者模式 VS 抽象工廠模式:
抽象工廠模式實(shí)現(xiàn)對(duì)產(chǎn)品家族的創(chuàng)建,一個(gè)產(chǎn)品家族:具有不同分類維度的產(chǎn)品組合,采用抽象工廠模式不需要關(guān)心構(gòu)建過(guò)程,只關(guān)心什么產(chǎn)品由什么工廠生產(chǎn)。
建造者模式是按照指定的要求創(chuàng)造產(chǎn)品,主要目的是通過(guò)組裝零件產(chǎn)生一個(gè)新產(chǎn)品。
總結(jié)
以上是生活随笔為你收集整理的mave工程中的一个类调用另一个聚合工程的一个类_谈谈设计模式:建造者模式在jdk中的体现,它和工厂模式区别?...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: git 只允许 源码_如何阻止离职员工盗
- 下一篇: yamlcpp遍历_OpenCV文件输入