https://blog.csdn.net/jack__chiang/article/details/70208886
1.設計模式的分類
創建型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。
結構型模式,共七種:適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。
行爲型模式,共十一種:策略模式、模板方法模式、觀察者模式、迭代器模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、解釋器模式。
1.工廠模式(Factory Method):
- 普通工廠模式
- 多個工廠方法模式
- 靜態工廠方法模式
1.1 普通工廠模式:
如果存在多個類實現了同一個接口,則這些類的實例化統一在一個”工廠類“中進行:
// 1. 發送短信和郵件的接口
public interface Sender {
public void Send();
}
//2.1 . 發送郵件的實現類
public class MailSender implements Sender {
public void Send() {
System.out.println("發送郵件!");
}
}
//2.2 . 發送短信的實現類
public class SmsSender implements Sender {
public void Send() {
System.out.println("發送短信!");
}
}
// 3 創建工廠類
public class SendFactory {
//工廠方法
public Sender produce(String type) {
if ("mail".equals(type)) {
return new MailSender();
} else if ("sms".equals(type)) {
return new SmsSender();
} else {
System.out.println("請輸入正確的類型!");
return null;
}
}
}
//測試類
public class FactoryTest {
public static void main(String[] args) {
SendFactory factory = new SendFactory();
Sender sender = factory.produce("sms");
sender.Send();
}
}
1.2 多個工廠模式
在普通方法模式基礎上,直接在工廠類中提供創建類實例的方法,而不需要先篩選下發字符:
//將上面的代碼做下修改,改動下SendFactory類就行
//這個就不用根據用戶傳的字符串類創建對象了
public class SendFactory {
public Sender produceMail(){
return new MailSender();
}
public Sender produceSms(){
return new SmsSender();
}
}
//測試類
public class FactoryTest {
public static void main(String[] args) {
SendFactory factory = new SendFactory();
Sender sender = factory.produceMail();
sender.Send();
}
}
1.3 靜態工廠方法模式
將上面多個工廠方法模式的方法設置爲靜態,不需要創建實例,直接調用:
public class SendFactory {
public static Sender produceMail(){
return new MailSender();
}
public static Sender produceSms(){
return new SmsSender();
}
}
//測試類
public class FactoryTest {
public static void main(String[] args) {
Sender sender = SendFactory.produceMail();
sender.Send();
}
}
總結:涉及到實現了一個接口的多個類的實例化時,創建一個“工廠類”,統一管理這些類的實例化過程;
2.抽象工廠模式:
把“工廠類”抽象化:
例子:
//發送短信和郵件的接口
public interface Sender {
public void Send();
}
//發送郵件的實現類
public class MailSender implements Sender {
public void Send() {
System.out.println("發送郵件!");
}
}
//發送短信的實現類
public class SmsSender implements Sender {
public void Send() {
System.out.println("發送短信!");
}
}
//給工廠類一個接口
public interface Provider {
public Sender produce();
}
//兩個工廠的實現類
public class SendMailFactory implements Provider {
public Sender produce(){
return new MailSender();
}
}
public class SendSmsFactory implements Provider{
public Sender produce() {
return new SmsSender();
}
}
//測試類
public class Test {
public static void main(String[] args) {
//實例化一個工廠類
Provider provider = new SendMailFactory();
// 通過工廠類實例化需要創建的類
Sender sender = provider.produce();
sender.Send();
}
}
總結:之前是一個工廠類可以實例化多個最終類,現在是多個工廠類,每個工廠類僅僅就實例化一個最終類,把最終類的多樣性轉移到工廠類的多樣性上;
簡單點說,類似於利用多態性,如果B extends A ,B 中重寫的A 中的方法,在創建A 時調用 A a = new B(); 則後續對a 的方法的調用實際上調用B 中的;
Provider provider = new SendMailFactory(); Provider 是一個抽象類,provider 是一個抽象類的實例化對象,如果向修改provider 以後的操作,可以就修改 new 後面的方法,增加拓展性!!!!
其實還可以寫一個類,繼承SendMailFactory?
3.單例模式(Singleton)
在Java應用中,單例對象能保證在一個JVM中,該對象只有一個實例存在。這樣的模式有幾個好處:
1.減少反覆創建同一個類的系統壓力;
2.省去new ,減輕GC;
//TODO
4.建造者模式(Builder)
google 源碼中很常見的模式, 類在創建一個再一步步“填寫”它的成員變量,方法;
class A {
int a;
long b;
string c;
void set_a(int new_a){ ... }
void set_b(long new_b){ ... }
...
...
int get_a();
long get_b();
...
}
5.原型模式(Prototype)
將一個對象作爲原型,對其進行復制、克隆,產生一個和原對象類似的新對象。在Java中,複製對象是通過clone()實現的:
public class Prototype implements Cloneable {
public Object clone() throws CloneNotSupportedException {
Prototype proto = (Prototype) super.clone();
return proto;
}
}
一個原型類,只需要實現Cloneable接口,覆寫clone方法,此處clone方法可以改成任意的名稱,因爲Cloneable接口是個空接口,你可以任意定義實現類的方法名,如cloneA或者cloneB,因爲此處的重點是super.clone()這句話,super.clone()調用的是Object的clone()方法,而在Object類中,clone()是native的,說明這個方法實現並不是使用java語言
//TODO FURTHER DISCUSSING
結構型模式
6.適配器模式(Adapter)
類似於
A extends B implement C
這樣A 的實例對象中,既可以調用B中實現的方法,也可以調用C 的方法。如果B 和C 需要進行通信,就可以直接在A中進行參數處理;
6.1 對象適配器模式
類似於
class A implement C {
public A( B b){
this.b = b;
}
}
B 是A的構造參數,在A 的實例對象裏可以直接調用B的信息,同時A 是C的實現類,A 中也可以調用C 的參數,最終B/C 通信;
6.2 接口適配器模式
A 爲接口類, B 爲抽象類且同時實現了A ,C extends B,重寫方法
public interface A {
public void method_A();
}
public abstract B implement A {
public void method_A(){
....
};
}
class C extends B {
// 重寫
public void method_A(){
....
};
public void method_C(){
... ...
}
}