設(shè)計(jì)模式
目前來(lái)說(shuō)最好理解的博客:
http://www.itdecent.cn/p/61b67ca754a3
1、單例模式
1.1、惡漢
//類(lèi)創(chuàng)建就加載
public class Singleton{
private static Singleton instance = new Singleton();
public static Singleton getInstance(){
return instance ;
}
1.1、懶漢
//需要用的時(shí)候才創(chuàng)建
public class Singleton02{
private static Singleton02 instance;
public static Singleton02 getInstance(){
if (instance == null){
synchronized (Singleton02.class){
if (instance == null){
instance = new Singleton02();
}
}
}
return instance;
}
}
2、工廠模式
2.1、簡(jiǎn)單工廠
定義:簡(jiǎn)單地說(shuō),簡(jiǎn)單工廠模式通常就是這樣,一個(gè)工廠類(lèi) XxxFactory,里面有一個(gè)靜態(tài)方法,根據(jù)我們不同的參數(shù),返回不同的派生自同一個(gè)父類(lèi)(或?qū)崿F(xiàn)同一接口)的實(shí)例對(duì)象。
public class FoodFactory {
public static Food makeFood(String name) {
if (name.equals("noodle")) {
Food noodle = new LanZhouNoodle();
noodle.addSpicy("more");
return noodle;
} else if (name.equals("chicken")) {
Food chicken = new HuangMenChicken();
chicken.addCondiment("potato");
return chicken;
} else {
return null;
}
}
}
2.2、工廠方法
定義:核心在于,我們需要在第一步選好我們需要的工廠。
第一步,我們需要選取合適的工廠,然后第二步基本上和簡(jiǎn)單工廠一樣。
public interface FoodFactory {
Food makeFood(String name);
}
public class ChineseFoodFactory implements FoodFactory {
@Override
public Food makeFood(String name) {
if (name.equals("A")) {
return new ChineseFoodA();
} else if (name.equals("B")) {
return new ChineseFoodB();
} else {
return null;
}
}
}
public class AmericanFoodFactory implements FoodFactory {
@Override
public Food makeFood(String name) {
if (name.equals("A")) {
return new AmericanFoodA();
} else if (name.equals("B")) {
return new AmericanFoodB();
} else {
return null;
}
}
}
// 客戶(hù)端調(diào)用
public class APP {
public static void main(String[] args) {
// 先選擇一個(gè)具體的工廠
FoodFactory factory = new ChineseFoodFactory();
// 由第一步的工廠產(chǎn)生具體的對(duì)象,不同的工廠造出不一樣的對(duì)象
Food food = factory.makeFood("A");
}
}
2.3、抽象工廠
定義:當(dāng)涉及到產(chǎn)品族的時(shí)候,就需要引入抽象工廠模式了。
一個(gè)經(jīng)典的例子是造一臺(tái)電腦。我們先不引入抽象工廠模式,看看怎么實(shí)現(xiàn)。
因?yàn)殡娔X是由許多的構(gòu)件組成的,我們將 CPU 和主板進(jìn)行抽象,然后 CPU 由 CPUFactory 生產(chǎn),主板由 MainBoardFactory 生產(chǎn),然后,我們?cè)賹?CPU 和主板搭配起來(lái)組合在一起,如下圖:

這個(gè)時(shí)候的客戶(hù)端調(diào)用是這樣的:
// 得到 Intel 的 CPU
CPUFactory cpuFactory = new IntelCPUFactory();
CPU cpu = intelCPUFactory.makeCPU();
// 得到 AMD 的主板
MainBoardFactory mainBoardFactory = new AmdMainBoardFactory();
MainBoard mainBoard = mainBoardFactory.make();
// 組裝 CPU 和主板
Computer computer = new Computer(cpu, mainBoard);
單獨(dú)看 CPU 工廠和主板工廠,它們分別是前面我們說(shuō)的工廠模式。這種方式也容易擴(kuò)展,因?yàn)橐o電腦加硬盤(pán)的話(huà),只需要加一個(gè) HardDiskFactory 和相應(yīng)的實(shí)現(xiàn)即可,不需要修改現(xiàn)有的工廠。但是,這種方式有一個(gè)問(wèn)題,那就是如果 Intel 家產(chǎn)的 CPU 和 AMD 產(chǎn)的主板不能兼容使用,那么這代碼就容易出錯(cuò),因?yàn)榭蛻?hù)端并不知道它們不兼容,也就會(huì)錯(cuò)誤地出現(xiàn)隨意組合。
下面就是我們要說(shuō)的產(chǎn)品族的概念,它代表了組成某個(gè)產(chǎn)品的一系列附件的集合:

當(dāng)涉及到這種產(chǎn)品族的問(wèn)題的時(shí)候,就需要抽象工廠模式來(lái)支持了。我們不再定義 CPU 工廠、主板工廠、硬盤(pán)工廠、顯示屏工廠等等,我們直接定義電腦工廠,每個(gè)電腦工廠負(fù)責(zé)生產(chǎn)所有的設(shè)備,這樣能保證肯定不存在兼容問(wèn)題。

這個(gè)時(shí)候,對(duì)于客戶(hù)端來(lái)說(shuō),不再需要單獨(dú)挑選 CPU廠商、主板廠商、硬盤(pán)廠商等,直接選擇一家品牌工廠,品牌工廠會(huì)負(fù)責(zé)生產(chǎn)所有的東西,而且能保證肯定是兼容可用的。
public static void main(String[] args) {
// 第一步就要選定一個(gè)“大廠”
ComputerFactory cf = new AmdFactory();
// 從這個(gè)大廠造 CPU
CPU cpu = cf.makeCPU();
// 從這個(gè)大廠造主板
MainBoard board = cf.makeMainBoard();
// 從這個(gè)大廠造硬盤(pán)
HardDisk hardDisk = cf.makeHardDisk();
// 將同一個(gè)廠子出來(lái)的 CPU、主板、硬盤(pán)組裝在一起
Computer result = new Computer(cpu, board, hardDisk);
}
當(dāng)然,抽象工廠的問(wèn)題也是顯而易見(jiàn)的,比如我們要加個(gè)顯示器,就需要修改所有的工廠,給所有的工廠都加上制造顯示器的方法。這有點(diǎn)違反了對(duì)修改關(guān)閉,對(duì)擴(kuò)展開(kāi)放這個(gè)設(shè)計(jì)原則。
3、策略模式
4、裝飾模式
裝飾者模式:若要擴(kuò)展功能,裝飾者提供了比集成更有彈性的替代方案,動(dòng)態(tài)地將責(zé)任附加到對(duì)象上。
-
1、裝備的超類(lèi):IEquip.java
2、各個(gè)裝備的實(shí)現(xiàn)類(lèi):
eg:武器的實(shí)現(xiàn)類(lèi): ArmEquip.java* 3、裝飾品的超類(lèi)(裝飾品也屬于裝備):IEquipDecorator.java
4、裝飾品的實(shí)現(xiàn)類(lèi):
eg:藍(lán)寶石的實(shí)現(xiàn)類(lèi)(可累加): BlueGemDecorator.java
5、最后測(cè)試:計(jì)算攻擊力和查看描述:
Log.e("---", "一個(gè)鑲嵌2顆紅寶石,1顆藍(lán)寶石的靴子: ");
IEquip iEquip = new RedGemDecotator(new RedGemDecotator(new BlueGemDecotator(new ShoeEquip())));
Log.e("---", "攻擊力:" + iEquip.caculateAttack());
Log.e("---", "描述語(yǔ):" + iEquip.description());
5、代理模式
定義:為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪(fǎng)問(wèn)。在某些情況下,一個(gè)客戶(hù)不想或者不能直接引用另一個(gè)對(duì)象,而代理對(duì)象可以在客戶(hù)端和目標(biāo)對(duì)象之間起到中介的作用。
比如:微商。一般都是廠家委托給代理商進(jìn)行銷(xiāo)售,顧客跟代理商打交道,而不直接與產(chǎn)品實(shí)際生產(chǎn)者進(jìn)行關(guān)聯(lián)。
6、建造者模式
7、觀察者模式
實(shí)際生活的例子:下面就以微信服務(wù)號(hào)為背景,給大家介紹觀察者模式。
Java開(kāi)發(fā)中的例子:RabbitMQ

如上圖所示,服務(wù)號(hào)就是我們的主題,使用者就是觀察者?,F(xiàn)在我們明確下功能:
- 服務(wù)號(hào)就是主題,業(yè)務(wù)就是推送消息
- 觀察者只需要訂閱主題,只要有新的消息就會(huì)送來(lái)
- 當(dāng)不想要此主題消息時(shí),取消訂閱
- 只要服務(wù)號(hào)還在,就可以一直有人訂閱
8、適配器模式
定義:將一個(gè)類(lèi)的接口轉(zhuǎn)換成客戶(hù)期望的另一個(gè)接口,適配器讓原本接口不兼容的類(lèi)可以相互合作。這個(gè)定義還好,說(shuō)適配器的功能就是把一個(gè)接口轉(zhuǎn)成另一個(gè)接口。
- 以充電器為實(shí)例: 手機(jī)充電器一般都是5V左右吧,咱天朝的家用交流電壓220V,所以手機(jī)充電需要一個(gè)適配器(降壓器)


9、外觀模式
定義:提供一個(gè)統(tǒng)一的接口,用來(lái)訪(fǎng)問(wèn)子系統(tǒng)中的一群接口,外觀定義了一個(gè)高層的接口,讓子系統(tǒng)更容易使用。其實(shí)就是為了方便客戶(hù)的使用,把一群操作,封裝成一個(gè)方法。
工作中的例子:
APP的首頁(yè)需要讀取很多接口,如:廣告,商品,活動(dòng),分類(lèi)等等。使用外觀模式可以將所有的接口整合成一個(gè)接口,統(tǒng)一輸出。
參考
https://blog.csdn.net/lmj623565791/article/details/25837275