常見的幾種設計模式

常見的設計模式(資料:《設計模式》,青島東合信息技術有限公司編著,電子工業出版社出版,ISBN:978-7-121-15582-6)
例子代碼:https://github.com/Youyou-0826/disign_pattern.git


1. 單一職責原則(single reposibility principle)
定義類時必須考慮職責與對象之間的關係。




2. 里氏替換原則(Liskov substitution principle)
使用基類的地方,子類一定適用。
①子類必須完全實現父類的方法;
②子類可以有自己的個性
③覆蓋或實現父類的方法時輸入參數可以被放大;
④覆蓋或實現父類的方法時輸出結果可以被縮小。
策略模式,組合模式,代理模式體現了“里氏替換原則”。




3. 依賴倒置原則(dependence inversion principle)
①模塊間的依賴通過抽象發生,實現類之間不發生直接的依賴關係,其依賴是通過接口或抽象類發生的;
②接口或抽象類不依賴於實現類;
③實現類依賴於就扣或抽象類。




4. 接口隔離原則(interface segregation principle)
只提供調用者需要的方法,屏蔽不需要的方法。
應儘量使用原子接口和原子類:
①一個藉口只對一個子模塊或者業務邏輯進行服務;
②只保留接口中業務邏輯需要的public方法;
③儘量修改污染了的接口,若修改的風險較大,這可才使用適配器模式進行轉化處理;




5. 迪米特法則(law of demeter)
一個對象應當其他對象儘可能少的瞭解。
外觀模式,中介者模式體現了迪米特原則。




6. 開閉原則(open-closed principle)
軟件實體應當對擴展開放,對修改關閉。






一. 單例模式
確保一個類中只有一個實例,而且自行實例化並向整個系統提供這個實例。
①餓漢式單例:類加載時就進行對象實例化。
public class Singleton {
private static Singleton instance = new Singleton();
//構造方法私有,外界無法直接實例化
private Singleton() {
}


public static Singleton getInstance() {
return instance;
}
}


②懶漢式單例:第一次引用類時才進行對象實例化,更符合java語言的特點。
public class Singleton {
private static Singleton instance = null;


private Singleton() {
}


synchroinzed public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}


使用單例模式的場景:
要求生成唯一的序列號,web網頁的計數器,IO資源和數據庫訪問,需要頻繁使用的工具類等。




二. 工廠方法
定義一個創建產品對象的工廠接口,將實際創建性工作推遲到子類中。
定義一個用於創建對象的接口,讓子類實例化哪個類。


public interface Creator {
/**
*工廠方法
*創建一個產品對象,輸入參數可以自行設置
*/
public <T extends Product> T factory(Class<T> c);
}


public interface Product {
//產品類的公共方法
public void method1();


public void method2();
}


public class ConcreteCreator implements Creator {
public <T extends Product> T factory(Class<T> c) {
Product product = null;
try{
product = (Product) Class.forName(c.getName()).newInstance();
}catch(Exception e) {
}
return (T) product;
}
}


public class ConcreteProduct implements Product {
public void method1() {
//公共業務處理
}


public method2() {
//業務處理邏輯
}
}




三. 抽象工廠
爲創建一組相關或相互依賴的對象提供一個接口,而且無需指定他們的具體類。在有多個業務品種,業務分類時,通過抽象工廠產生所需對象是一種很好的解決方式。


public interface AbstractFactory {
//創建產品A
public ProductA factoryA();
//創建產品B
public ProductB factoryB();
}


public class ConcreteFactory1 implements AbstractFactory {
//創建等級爲1的產品A
public ProductA factoryA() {
return new ProductA1();
}


//創建等級爲1的產品B
public ProductB factoryB() {
return new ProductB1();
}
}


public class ConcreteFactory2 implements AbstractFactory {
//創建等級爲2的產品A
public ProductA factoryA() {
return new ProductA2();
}


//創建等級爲2的產品B
public ProductB factoryB() {
return new ProductB2();
}
}


public interface ProductA {
//產品A的方法
public void method1();
public void method2();
}


public class ProductA1 implements ProductA {
public void method1() {
//等級爲1的產品A
}


public void method2() {
//業務邏輯
}
}


public class ProductA2 implements ProductA {
public void method1() {
//等級爲2的產品A
}


public void method2() {
//業務邏輯
}
}




四. 建造者模式
將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。


public class Product {
//產品業務處理方法
}


public abstract class Builder {
//設置產品的不同部分以獲得不同產品
public abstract void setPart1();
public abstract void setPart2();
public abstract void setPart3();
//其他部分


//建造產品
public abstract Product builderProduct();
}


public class ConcreteBuilder extends Builder {
private Product product = new Product();
//設置產品零件
public void setPart1() {
//設置part1
}


public void setPart2() {
//設置part2
}


public void setPart3() {
//設置part3
}


//生產一個產品
public Product builderProduct() {
return product;
}
}


public class Director {
private Builder builder = new ConcreteBuilder();


//構造產品,負責調用各個零件構造方法
public Product build() {
builder.setPart1();
builder.setPart2();
builder.setPart3();
//其他部件
return builder.builderProduct();
}
}


建造者模式的使用場景:產品類複雜,多個部件和零件多可裝到同一個對象中,產生結果不同,多個方法,不同調用順序產生不同結果。




五. 原型模式
用原型實例指定創建對象的種類,並且通過複製這些原型創建新的對象。
public interface ClientDemo extends Cloneable {
//克隆方法
Prototype clone();
}


public class ConcretePrototype implements Prototype {
public Prototype clone() {
try {
return (Prototype) super.clone();
}catch(CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}


public class Client {
public void operation(Prototype example) {
//得到example的副本
Prototype p = example.clone();
}
}


原型模式的使用場景:
資源優化場景,性能和安全要求場景,一個對象多個修改者的場景。




六. 代理模式
爲其他對象提供一種代理以控制對這個對象的訪問。


public interface Subject {
//定義一個請求方法
public void request();
}


public class RealSubject implements Subject {
private void request() {
//具體業務邏輯
}
}


public class ProxySubject implements Subject {
private Subject subject;


public ProxySubject(Subject subject) {
this.subject = subject;
}


//實現請求方法
public void request() {
this.beforeRequest();
this.request();
this.afterRequest();
}


//實現請求前的操作
private void beforeRequest() {
//預處理
}


//請求後的操作
private void afterRequest() {
//善後處理
}
}
代理模式的優點:職責清晰,高擴展性,智能化,是一種很常用的模式




七. 裝飾模式
動態的給一個對象添加一些額外的職責,就增加功能來說,裝飾模式比生成子類更爲靈活。
抽象構件角色
具體構件角色
裝飾角色
具體裝飾角色


public interface Compontent {
public void operation();
}


public class ConcreteComponent implements Compontent {
public void operation() {
//具體業務
}
}


public abstract class Decorator implements Component {
private Component component = null;


public Decorator(Component component) {
this.component = component;
}


public void operation() {
this.component.operation();
}
}


public class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}


//定義自己的方案
private void method() {
System.out.println("decoration...");
}


//重寫operation方法
public void operation() {
this.method();
super.operation();
}
}


public class Client {
public static void main(String[] args) {
Component component = new ConcreteComponent();
//進行裝飾
component = new ConcreteComponent(component);
component.operation();
}
}




八. 適配器模式
將一個類接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起工作的兩個類能夠在一起工作。
涉及源,目標角色和適配器角色。


public class Adaptee {
//原有的業務處理邏輯
public void specificRequest() {
}
}


public interface Target {
public void request() {
}
}


public class Adapter extends Adaptee implements Target {
public void request() {
super.specificRequest();
}
}


public class Client {
public static void main(String[] args) {
//適配器模式的應用
Target target = new Adapter();
target.request();
}
}




九.  外觀模式
要求子系統的外部與其內部的通信必須通過一個統一的對象進行,外觀模式提供一個高層次的接口,使得子系統容易使用。


public class ClassA {
public void methodA() {
}
}


public class ClassB {
public void methodB() {
}
}


public class ClassC {
public void methodC() {
}
}


public class Facade {
//被委託的對象
private ClassA a = new ClassA();
private ClassB b = new ClassB();
private ClassC c = new ClassC();
//提供臨界的方法
public void methodA() {
a.methodA();
}


public void methodB() {
b.methodB();
}


public void methodC() {
c.methodC();
}
}




十. 模板方法
定義一個操作中的算法的框架,而將一些步驟延遲到子類中,使得子類可以改變一個算法的結構,即可定義該算法的某些特定步驟。


public abstract class AbstractClass {
//基本方法
protected abstract void operation();


//模板方法
public void templateMethod() {
//調用基本方法,完成相關邏輯
this.operation();
}
}


public class ConcreteClass extends AbstractClass {
//實現基本業務方法
protected void operation() {
//業務邏輯
}
}


public class Client {
public static void main(String[] args) {
AbstractClass abstractClass = new ConcreteClass();
//調用模板方法
abstractClass.templateMethod();
}
}




十一. 策略模式
定義一組算法,將每個方法都封裝起來,並且使他們之間可以互換。
其用意是針對一組算法,將每一個算法封裝到具有共同接口的獨立的類中,從而使得它們可以相互替換,使得算法可以在不影響客戶端的情況下發生變化。


public abstract class Strategy {
//策略方法
public abstract void strategyInterface();
}


//具體策略類
public class ConcreteStrategy extends Strategy {
//實現策略方法
public void strategyInterface() {
//具體算法
}
}


public class Context {
private Strategy strategy = null;


//構造函數
public Context(Strategy strategy) {
this.strategy = strategy;
}


//策略方法
public void contextInterface() {
this.strategy.strategyInterface();
}
}




十二. 迭代器模式
提供一種方法訪問一個容器對象中各個元素,而又不暴露該對象的內部細節。


public interface Iterator {
public Object next();


public boolean hasNext();
}


public class ConcreteIterator implements Iterator {
private ConcreteAggregate agg;
private int index = 0;
private int size = 0;


public ConcreteIterator(ConcreteAggregate agg) {
this.agg = agg;
size = agg.size();
index = 0;
}


public boolean hasNext() {
return index < size;
}


public Object next() {
if(index < size) {
return agg.getElement(index++);
} else {
return null;
}
}
}


public interface Aggregate {
public void add(Object obj);


public Iterator creatIterator();
}


public class ConcreteAggregate implements Aggregate {
private Vector vector = new Vector();


public void add(Object object) {
this.vector.add(object);
}


public Object getElement(int index) {
if(index < vector.size()) {
return vector.get(index);
} else {
return null;
}
}


public int size() {
return vector.size();
}


public Iterator creatIterator() {
return new ConcreteIterator(this);
}
}




十三. 觀察者模式
定義對象間一種一對多的依賴關係,使得每當一個對象改變狀態時,則所有依賴於它的對象都會得到通知並被自動更新。


public interface Subject {
public void attach(Observer observer);


public void detach(Observer observer);


public void notifyObserver();
}


public interface Observer {
public void update();
}


public class ConcreteSubject implements Subject {
private Vector<Observer> obsVector = new Vector<Observer>();


public void attach(Observer observer) {
obsVector.add(observer);
}


public void detach(Observer observer) {
obsVector.remove(observer);
}


public void notifyObserver() {
for(Observer obs : obsVector) {
obs.update();
}
}


public Enumeration<Observer> observers() {
return obsVector.elements();
}


public void change() {
this.notifyObserver();
}
 }


 public class ConcreteObserver implements Observer {
  //實現更新方法
  public void update() {
  System.out.println("updated...");
  }
 }


 public class Client {
  public static void main(String[] args) {
  ConcreteSubject subject = new ConcreteSubject();
  Observer observer = new ConcreteObserver();
  subject.attach(observer);
  subject.change();
  }
 }
發佈了51 篇原創文章 · 獲贊 45 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章