引言

在Java編程的世界里,設(shè)計(jì)模式如同武林秘籍,掌握了它們,便能在軟件開發(fā)的道路上行走得更遠(yuǎn)、更穩(wěn)。設(shè)計(jì)模式是對常見問題的解決方案的高度抽象,它們不僅提升了代碼的可讀性和可維護(hù)性,還使得軟件架構(gòu)更加靈活和健壯。本文將詳細(xì)解析Java中的23種經(jīng)典設(shè)計(jì)模式,并輔以實(shí)際應(yīng)用實(shí)例,幫助讀者深入理解和掌握這些寶貴的編程智慧。

設(shè)計(jì)模式的分類

設(shè)計(jì)模式主要分為三大類:創(chuàng)建型模式、結(jié)構(gòu)型模式和行為型模式。

1. 創(chuàng)建型模式(5種)

1.1 單例模式(Singleton)

核心原理:確保一個(gè)類只有一個(gè)實(shí)例,并提供一個(gè)全局訪問點(diǎn)。

優(yōu)點(diǎn)

  • 資源控制:避免多次創(chuàng)建同一對象造成的資源浪費(fèi)。
  • 全局訪問:方便地在整個(gè)應(yīng)用中訪問單例對象。

缺點(diǎn)

  • 違反單一職責(zé)原則:單例類可能承擔(dān)過多職責(zé)。
  • 擴(kuò)展困難:缺乏抽象層,功能擴(kuò)展不便。

適用場景:數(shù)據(jù)庫連接、日志對象、配置管理器等。

示例代碼

public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
1.2 工廠方法模式(Factory Method)

核心原理:定義一個(gè)用于創(chuàng)建對象的接口,但讓子類決定要實(shí)例化哪個(gè)類。

優(yōu)點(diǎn)

  • 解耦:將對象的創(chuàng)建和使用分離。
  • 靈活性:子類可以靈活地決定實(shí)例化哪個(gè)類。

缺點(diǎn)

  • 類數(shù)量增加:每增加一個(gè)產(chǎn)品類,就需要增加一個(gè)對應(yīng)的工廠類。

適用場景:需要根據(jù)不同條件創(chuàng)建不同對象的情況。

示例代碼

interface Product {
    void use();
}

class ConcreteProductA implements Product {
    @Override
    public void use() {
        System.out.println("Using Product A");
    }
}

class ConcreteProductB implements Product {
    @Override
    public void use() {
        System.out.println("Using Product B");
    }
}

abstract class Creator {
    public abstract Product factoryMethod();
}

class ConcreteCreatorA extends Creator {
    @Override
    public Product factoryMethod() {
        return new ConcreteProductA();
    }
}

class ConcreteCreatorB extends Creator {
    @Override
    public Product factoryMethod() {
        return new ConcreteProductB();
    }
}
1.3 抽象工廠模式(Abstract Factory)

核心原理:提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對象的接口,而無需指定它們具體的類。

優(yōu)點(diǎn)

  • 解耦:客戶端與具體類解耦。
  • 擴(kuò)展性:增加新的產(chǎn)品族較為容易。

缺點(diǎn)

  • 復(fù)雜性增加:增加了系統(tǒng)的復(fù)雜性。

適用場景:需要?jiǎng)?chuàng)建一系列相關(guān)或相互依賴對象的情況。

示例代碼

interface AbstractFactory {
    ProductA createProductA();
    ProductB createProductB();
}

class ConcreteFactory1 implements AbstractFactory {
    @Override
    public ProductA createProductA() {
        return new ConcreteProductA1();
    }

    @Override
    public ProductB createProductB() {
        return new ConcreteProductB1();
    }
}

interface ProductA {
    void use();
}

class ConcreteProductA1 implements ProductA {
    @Override
    public void use() {
        System.out.println("Using Product A1");
    }
}

interface ProductB {
    void use();
}

class ConcreteProductB1 implements ProductB {
    @Override
    public void use() {
        System.out.println("Using Product B1");
    }
}
1.4 建造者模式(Builder)

核心原理:將一個(gè)復(fù)雜對象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。

優(yōu)點(diǎn)

  • 分離構(gòu)建和表示:使得構(gòu)建過程和表示過程。
  • 易于擴(kuò)展:可以方便地添加新的構(gòu)建步驟。

缺點(diǎn)

  • 類數(shù)量增加:增加了系統(tǒng)的復(fù)雜性。

適用場景:需要?jiǎng)?chuàng)建復(fù)雜對象且對象的創(chuàng)建過程和表示分離的情況。

示例代碼

public class ComplexObject {
    private String partA;
    private String partB;
    private String partC;

    private ComplexObject(Builder builder) {
        this.partA = builder.partA;
        this.partB = builder.partB;
        this.partC = builder.partC;
    }

    public static class Builder {
        private String partA;
        private String partB;
        private String partC;

        public Builder setPartA(String partA) {
            this.partA = partA;
            return this;
        }

        public Builder setPartB(String partB) {
            this.partB = partB;
            return this;
        }

        public Builder setPartC(String partC) {
            this.partC = partC;
            return this;
        }

        public ComplexObject build() {
            return new ComplexObject(this);
        }
    }
}
1.5 原型模式(Prototype)

核心原理:用原型實(shí)例指定創(chuàng)建對象的種類,并通過拷貝這些原型創(chuàng)建新的對象。

優(yōu)點(diǎn)

  • 性能提升:在某些情況下,復(fù)制對象比創(chuàng)建新對象更高效。
  • 靈活性:可以動(dòng)態(tài)地獲取對象的運(yùn)行時(shí)類型。

缺點(diǎn)

  • 復(fù)制過程復(fù)雜:某些對象的復(fù)制過程可能較為復(fù)雜。

適用場景:需要大量創(chuàng)建相同或相似對象的情況。

示例代碼

public class Prototype implements Cloneable {
    private String field;

    public Prototype(String field) {
        this.field = field;
    }

    public void setField(String field) {
        this.field = field;
    }

    public String getField() {
        return field;
    }

    @Override
    public Prototype clone() throws CloneNotSupportedException {
        return (Prototype) super.clone();
    }
}

2. 結(jié)構(gòu)型模式(7種)

2.1 適配器模式(Adapter)

核心原理:將一個(gè)類的接口轉(zhuǎn)換成客戶端所期待的接口,使原本接口不兼容的類可以一起工作。

優(yōu)點(diǎn)

  • 解耦:客戶端與具體類解耦。
  • 復(fù)用性:提高了類的復(fù)用性。

缺點(diǎn)

  • 過多使用適配器可能導(dǎo)致系統(tǒng)復(fù)雜。

適用場景:需要將一個(gè)類的接口轉(zhuǎn)換成另一個(gè)接口的情況。

示例代碼

interface Target {
    void request();
}

class Adaptee {
    public void specificRequest() {
        System.out.println("Adaptee specific request");
    }
}

class Adapter implements Target {
    private Adaptee adaptee;

    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void request() {
        adaptee.specificRequest();
    }
}
2.2 裝飾器模式(Decorator)

核心原理:動(dòng)態(tài)地給一個(gè)對象添加一些額外的職責(zé),而不改變其接口。

優(yōu)點(diǎn)

  • 靈活性:可以動(dòng)態(tài)地添加職責(zé)。
  • 可擴(kuò)展性:易于擴(kuò)展新的裝飾器。

缺點(diǎn)

  • 過多裝飾器可能導(dǎo)致系統(tǒng)復(fù)雜。

適用場景:需要?jiǎng)討B(tài)地給對象添加職責(zé)的情況。

示例代碼

interface Component {
    void operation();
}

class ConcreteComponent implements Component {
    @Override
    public void operation() {
        System.out.println("ConcreteComponent operation");
    }
}

abstract class Decorator implements Component {
    protected Component component;

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

    @Override
    public void operation() {
        component.operation();
    }
}

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

    @Override
    public void operation() {
        super.operation();
        System.out.println("ConcreteDecoratorA operation");
    }
}
2.3 代理模式(Proxy)

核心原理:為其他對象提供一個(gè)代理以控制對這個(gè)對象的訪問。

優(yōu)點(diǎn)

  • 控制訪問:可以控制對對象的訪問。
  • 功能增強(qiáng):可以在代理中添加額外的功能。

缺點(diǎn)

  • 性能開銷:增加了系統(tǒng)的性能開銷。

適用場景:需要控制對對象的訪問或增強(qiáng)對象功能的情況。

示例代碼

interface Subject {
    void request();
}

class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("RealSubject request");
    }
}

class Proxy implements Subject {
    private RealSubject realSubject;

    @Override
    public void request() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        preRequest();
        realSubject.request();
        postRequest();
    }

    private void preRequest() {
        System.out.println("Proxy preRequest");
    }

    private void postRequest() {
        System.out.println("Proxy postRequest");
    }
}
2.4 外觀模式(Facade)

核心原理:為子系統(tǒng)中的一組接口提供一個(gè)統(tǒng)一的接口,使得子系統(tǒng)更容易使用。

優(yōu)點(diǎn)

  • 簡化接口:簡化了客戶端的使用。
  • 解耦:客戶端與子系統(tǒng)解耦。

缺點(diǎn)

  • 不易擴(kuò)展:增加新的子系統(tǒng)可能需要修改外觀類。

適用場景:需要簡化復(fù)雜子系統(tǒng)接口的情況。

示例代碼

class SubSystemA {
    public void operationA() {
        System.out.println("SubSystemA operationA");
    }
}

class SubSystemB {
    public void operationB() {
        System.out.println("SubSystemB operationB");
    }
}

class Facade {
    private SubSystemA subSystemA;
    private SubSystemB subSystemB;

    public Facade() {
        subSystemA = new SubSystemA();
        subSystemB = new SubSystemB();
    }

    public void operation() {
        subSystemA.operationA();
        subSystemB.operationB();
    }
}
2.5 橋接模式(Bridge)

核心原理:將抽象部分與實(shí)現(xiàn)部分分離,使它們可以地變化。

優(yōu)點(diǎn)

  • 靈活性:抽象和實(shí)現(xiàn)可以變化。
  • 可擴(kuò)展性:易于擴(kuò)展新的抽象和實(shí)現(xiàn)。

缺點(diǎn)

  • 增加了系統(tǒng)的復(fù)雜性。

適用場景:需要將抽象和實(shí)現(xiàn)分離的情況。

示例代碼

interface Implementor {
    void operationImpl();
}

class ConcreteImplementorA implements Implementor {
    @Override
    public void operationImpl() {
        System.out.println("ConcreteImplementorA operationImpl");
    }
}

abstract class Abstraction {
    protected Implementor implementor;

    public Abstraction(Implementor implementor) {
        this.implementor = implementor;
    }

    public abstract void operation();
}

class RefinedAbstraction extends Abstraction {
    public RefinedAbstraction(Implementor implementor) {
        super(implementor);
    }

    @Override
    public void operation() {
        System.out.println("RefinedAbstraction operation");
        implementor.operationImpl();
    }
}
2.6 組合模式(Composite)

核心原理:將對象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu),使得客戶可以統(tǒng)一使用單個(gè)對象和組合對象。

優(yōu)點(diǎn)

  • 靈活性:可以靈活地添加和刪除組件。
  • 統(tǒng)一性:統(tǒng)一了單個(gè)對象和組合對象的使用。

缺點(diǎn)

  • 不易擴(kuò)展:增加新的組件類型可能需要修改現(xiàn)有類。

適用場景:需要表示“部分-整體”層次結(jié)構(gòu)的情況。

示例代碼

interface Component {
    void operation();
}

class Leaf implements Component {
    @Override
    public void operation() {
        System.out.println("Leaf operation");
    }
}

class Composite implements Component {
    private List<Component> children = new ArrayList<>();

    public void add(Component component) {
        children.add(component);
    }

    public void remove(Component component) {
        children.remove(component);
    }

    @Override
    public void operation() {
        for (Component child : children) {
            child.operation();
        }
    }
}
2.7 享元模式(Flyweight)

核心原理:運(yùn)用共享技術(shù)有效地支持大量細(xì)粒度的對象。

優(yōu)點(diǎn)

  • 節(jié)省內(nèi)存:通過共享對象減少內(nèi)存開銷。
  • 提高性能:減少了對象的創(chuàng)建和銷毀。

缺點(diǎn)

  • 復(fù)雜性增加:增加了系統(tǒng)的復(fù)雜性。

適用場景:需要大量創(chuàng)建相同或相似對象的情況。

示例代碼

interface Flyweight {
    void operation(String extrinsicState);
}

class ConcreteFlyweight implements Flyweight {
    private String intrinsicState;

    public ConcreteFlyweight(String intrinsicState) {
        this.intrinsicState = intrinsicState;
    }

    @Override
    public void operation(String extrinsicState) {
        System.out.println("IntrinsicState: " + intrinsicState);
        System.out.println("ExtrinsicState: " + extrinsicState);
    }
}

class FlyweightFactory {
    private Map<String, Flyweight> flyweights = new HashMap<>();

    public Flyweight getFlyweight(String key) {
        if (!flyweights.containsKey(key)) {
            flyweights.put(key, new ConcreteFlyweight(key));
        }
        return flyweights.get(key);
    }
}

3. 行為型模式(11種)

3.1 策略模式(Strategy)

核心原理:定義一系列算法,將每個(gè)算法封裝起來,并使它們可以互相替換。

優(yōu)點(diǎn)

  • 靈活性:算法可以靈活地替換。
  • 可擴(kuò)展性:易于添加新的算法。

缺點(diǎn)

  • 客戶端需要知道所有策略類:增加了客戶端的復(fù)雜性。

適用場景:需要?jiǎng)討B(tài)地選擇算法的情況。

示例代碼

interface Strategy {
    void execute();
}

class ConcreteStrategyA implements Strategy {
    @Override
    public void execute() {
        System.out.println("ConcreteStrategyA execute");
    }
}

class ConcreteStrategyB implements Strategy {
    @Override
    public void execute() {
        System.out.println("ConcreteStrategyB execute");
    }
}

class Context {
    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }

    public void executeStrategy() {
        strategy.execute();
    }
}
3.2 模板方法模式(Template Method)

核心原理:定義一個(gè)操作中的算法骨架,將一些步驟延遲到子類中實(shí)現(xiàn)。

優(yōu)點(diǎn)

  • 代碼復(fù)用:父類代碼可以被多個(gè)子類復(fù)用。
  • 可擴(kuò)展性:易于添加新的子類。

缺點(diǎn)

  • 不易修改:算法骨架固定,修改較為困難。

適用場景:需要定義算法骨架的情況。

示例代碼

abstract class AbstractClass {
    public final void templateMethod() {
        primitiveOperation1();
        primitiveOperation2();
        hookOperation();
    }

    protected abstract void primitiveOperation1();

    protected abstract void primitiveOperation2();

    protected void hookOperation() {
        // 默認(rèn)實(shí)現(xiàn),子類可以重寫
    }
}

class ConcreteClass extends AbstractClass {
    @Override
    protected void primitiveOperation1() {
        System.out.println("ConcreteClass primitiveOperation1");
    }

    @Override
    protected void primitiveOperation2() {
        System.out.println("ConcreteClass primitiveOperation2");
    }

    @Override
    protected void hookOperation() {
        System.out.println("ConcreteClass hookOperation");
    }
}
3.3 觀察者模式(Observer)

核心原理:定義對象間的一種一對多的依賴關(guān)系,當(dāng)一個(gè)對象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對象都得到通知并被自動(dòng)更新。

優(yōu)點(diǎn)

  • 解耦:目標(biāo)和觀察者解耦。
  • 靈活性:可以動(dòng)態(tài)地添加和刪除觀察者。

缺點(diǎn)

  • 性能開銷:過多的觀察者可能導(dǎo)致性能問題。

適用場景:需要實(shí)現(xiàn)事件訂閱和通知的情況。

示例代碼

interface Observer {
    void update();
}

class ConcreteObserverA implements Observer {
    @Override
    public void update() {
        System.out.println("ConcreteObserverA update");
    }
}

class ConcreteObserverB implements Observer {
    @Override
    public void update() {
        System.out.println("ConcreteObserverB update");
    }
}

class Subject {
    private List<Observer> observers = new ArrayList<>();

    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update();
        }
    }
}
3.4 迭代子模式(Iterator)

核心原理:提供一種方法順序訪問一個(gè)聚合對象中各個(gè)元素,而又不暴露其內(nèi)部的表示。

優(yōu)點(diǎn)

  • 解耦:客戶端與聚合對象解耦。
  • 靈活性:可以靈活地遍歷聚合對象。

缺點(diǎn)

  • 增加了系統(tǒng)的復(fù)雜性。

適用場景:需要遍歷聚合對象的情況。

示例代碼

interface Iterator {
    boolean hasNext();
    Object next();
}

class ConcreteIterator implements Iterator {
    private List<Object> items;
    private int position = 0;

    public ConcreteIterator(List<Object> items) {
        this.items = items;
    }

    @Override
    public boolean hasNext() {
        return position < items.size();
    }

    @Override
    public Object next() {
        return items.get(position++);
    }
}

interface Aggregate {
    Iterator createIterator();
}

class ConcreteAggregate implements Aggregate {
    private List<Object> items = new ArrayList<>();

    public void addItem(Object item) {
        items.add(item);
    }

    @Override
    public Iterator createIterator() {
        return new ConcreteIterator(items);
    }
}
3.5 責(zé)任鏈模式(Chain of Responsibility)

核心原理:使多個(gè)對象都有機(jī)會處理請求,從而避免請求的發(fā)送者和接收者之間的耦合關(guān)系。

優(yōu)點(diǎn)

  • 解耦:請求的發(fā)送者和接收者解耦。
  • 靈活性:可以靈活地添加和刪除處理者。

缺點(diǎn)

  • 請求可能不被處理:如果鏈中沒有適當(dāng)?shù)奶幚碚?,請求可能不被處理?/li>

適用場景:需要多個(gè)對象處理同一請求的情況。

示例代碼: “`java interface Handler {

void handleRequest();
void setNextHandler(Handler nextHandler);

}

class ConcreteHandlerA implements Handler {

private Handler nextHandler;

@Override
public void