设计模式全面教学PPT合集

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:设计模式是软件工程中的最佳实践,提供了一套可重用的解决方案模板,用于解决开发中常见的问题。本PPT合集详尽介绍了各种设计模式,包括单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式、观察者模式、装饰器模式、代理模式、适配器模式、桥接模式、组合模式、享元模式、状态模式、策略模式和模板方法模式。这些模式有助于编写灵活和可维护的代码,并适合初学者学习和理解。 设计模式PPT合集

1. 设计模式概念与重要性

设计模式是软件工程领域的一个重要概念,它们是在软件开发中被反复使用,并经过实践检验的模板和解决方案。设计模式能够帮助开发者以更加高效和结构化的方式构建软件系统,提升代码的可复用性、可维护性和扩展性。理解并熟练运用设计模式,对于任何有志于提升自身软件设计能力的开发人员来说,都是一块必不可少的敲门砖。在这一章中,我们将探讨设计模式的基本概念,并解释为什么设计模式对于现代软件开发至关重要。

设计模式通常分为三大类:创建型模式、结构型模式和行为型模式。创建型模式主要涉及对象实例化的过程,结构型模式处理类或对象的组合,而行为型模式则关注对象之间的交互和职责分配。不同的模式解决了软件设计中不同的问题,比如单例模式确保一个类只有一个实例,而工厂模式则用于创建对象,避免直接实例化对象,使得系统更加灵活和可扩展。

设计模式之所以重要,是因为它们提供了一种通用的沟通语言,让开发者之间能够更高效地交流思想。同时,通过复用经过验证的设计模式,开发者可以减少设计错误,缩短开发周期,并提高软件质量。设计模式是构建高质量、可扩展、可维护系统的基石,它们是连接理论与实践的桥梁,对于任何想在软件开发领域持续进步的个人来说,掌握它们是必不可少的技能。

2. 单例模式与应用场景

2.1 单例模式的定义和实现原理

2.1.1 单例模式的基本思想

单例模式(Singleton Pattern)是一种常用的软件设计模式。顾名思义,单例模式确保一个类只有一个实例,并提供一个全局访问点。该模式在计算机系统中广泛应用,尤其是当程序需要确保某个类只有一个对象存在或控制资源的共享时。单例模式可以避免对共享资源的多重占用,减少内存占用,提高性能。

2.1.2 单例模式的关键实现技术

实现单例模式的关键在于私有化类的构造器,确保它不能被外部直接创建实例,并在类内部创建这个唯一的实例。通常会有一个静态方法来提供这个实例的全局访问点。在多线程环境下,还需要考虑线程安全问题,以保证单例的唯一性不会因为并发访问而破坏。

以下是一个简单的单例模式的实现代码:

public class Singleton {
    // 私有静态实例,防止被引用
    private static Singleton instance = null;

    // 私有构造函数,防止被实例化
    private Singleton() {}

    // 静态公有方法,返回这个类的唯一实例
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

    // 如果需要的话,可以在这里添加一些操作
    public void doSomething() {
        // ...
    }
}

在多线程环境下,可以使用 Double-Checked Locking 模式来处理:

public class Singleton {
    private volatile static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }

    // 其他方法...
}

2.2 单例模式的实际应用场景

2.2.1 系统配置管理

在很多应用中,我们经常需要配置管理器来统一管理配置项。这些配置项通常需要被系统各个部分访问,使用单例模式可以很容易地实现配置的集中管理和访问。

2.2.2 线程池、日志对象等全局访问点

线程池、日志记录器等对象也需要在系统中被多个地方访问,而且这些对象在创建时需要消耗较多资源,使用单例模式可以保证线程池或日志对象只被初始化一次。

代码示例(日志记录器的单例实现):

public class Logger {
    private static Logger instance = new Logger();
    private List<String> logs = new ArrayList<>();

    private Logger() {}

    public static Logger getInstance() {
        return instance;
    }

    public void log(String message) {
        logs.add(message);
        System.out.println(message);
    }

    // 其他日志操作...
}

// 使用 Logger
public class Application {
    public static void main(String[] args) {
        Logger logger = Logger.getInstance();
        logger.log("App started");
        // ...
    }
}

以上为单例模式的定义、实现原理和应用场景的讨论,从基本思想的介绍,到关键实现技术的讲解,再到实际应用案例的展示,系统地阐明了单例模式在软件开发中的重要性和使用方式。

3. 工厂模式与抽象工厂模式

3.1 工厂模式的定义及实现

3.1.1 简单工厂模式

简单工厂模式是一个创建型设计模式,用来创建同一类对象,而不需要指定将要创建的对象的具体类。这种方式在面向对象设计中通常不被推荐,因为它违反了开闭原则,当增加新产品时,需要修改工厂类的判断逻辑。

public class SimpleFactory {
    // 工厂方法,根据参数创建不同类型的产品
    public Product createProduct(String type) {
        if ("A".equals(type)) {
            return new ProductA();
        } else if ("B".equals(type)) {
            return new ProductB();
        }
        throw new IllegalArgumentException("Unknown product type");
    }
}

在上述代码中, SimpleFactory 类中的 createProduct 方法负责创建产品,并根据传入的类型 type 来实例化 ProductA ProductB 。如果要增加新的产品类型,必须修改这个方法,加入新的判断逻辑。

3.1.2 工厂方法模式

工厂方法模式是简单工厂模式的延伸,它在父类中提供一个创建对象的方法,允许子类决定实例化对象的类型。这种方式支持了开闭原则,当添加新产品时,只需添加新的工厂子类即可。

public abstract class ProductFactory {
    // 抽象工厂方法,由子类实现
    abstract Product createProduct();

    // 可能还有其他辅助方法
}

public class ProductAFactory extends ProductFactory {
    Product createProduct() {
        return new ProductA();
    }
}

public class ProductBFactory extends ProductFactory {
    Product createProduct() {
        return new ProductB();
    }
}

ProductFactory 是一个抽象类,定义了一个抽象方法 createProduct ProductAFactory ProductBFactory ProductFactory 的子类,分别重写了 createProduct 方法以创建相应的产品实例。

3.1.3 抽象工厂模式

抽象工厂模式提供了一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。抽象工厂模式用于创建一系列相关或依赖对象,而工厂方法模式用于创建单个对象。

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

public class ConcreteFactory1 implements AbstractFactory {
    public ProductA createProductA() {
        return new ProductA1();
    }
    public ProductB createProductB() {
        return new ProductB1();
    }
}

public class ConcreteFactory2 implements AbstractFactory {
    public ProductA createProductA() {
        return new ProductA2();
    }
    public ProductB createProductB() {
        return new ProductB2();
    }
}

在这个例子中, AbstractFactory 是一个接口,定义了两个方法 createProductA createProductB ConcreteFactory1 ConcreteFactory2 分别实现了这个接口,并提供了具体产品的创建逻辑。如果需要增加一个新的产品族,只需要增加新的工厂类即可。

3.2 工厂模式的使用场景与优点

3.2.1 对象创建的封装

工厂模式隐藏了创建对象的复杂性,客户端只需要请求一个工厂对象,然后使用该工厂提供的方法来创建所需的产品对象。例如在数据库连接场景中,客户端不需要知道数据库连接的细节,只需要通过工厂类提供的方法获取一个数据库连接对象。

public class DatabaseConnector {
    private String connectionString;
    private Connection connection;

    public DatabaseConnector(String connectionString) {
        this.connectionString = connectionString;
    }

    public Connection connect() throws SQLException {
        // 实际的连接逻辑隐藏在下面
        connection = DriverManager.getConnection(connectionString);
        return connection;
    }

    // 其他数据库操作方法
}

客户端代码中,我们只需要如下调用:

DatabaseConnector connector = new DatabaseConnector("jdbc:mysql://localhost:3306/mydb");
Connection dbConnection = connector.connect();

客户端代码不需要关心 DriverManager.getConnection() 的具体实现细节,只需知道通过工厂对象可以得到一个连接对象。

3.2.2 代码解耦与系统的可扩展性

工厂模式通过将对象创建的职责从应用程序代码中分离出来,来实现代码的解耦。这种方式使得应用程序不依赖于具体类的创建逻辑,提高系统的可扩展性和维护性。

  • 解耦 : 应用程序不需要关心产品对象的创建过程,只关心产品对象本身。
  • 扩展性 : 当产品类发生变化时,可以不修改客户端代码,只需要修改工厂代码即可。
  • 可维护性 : 不同的产品类可能有不同的构造逻辑,工厂模式可以集中管理这些逻辑。
classDiagram
    class Client {
        +requestProduct()
    }
    class AbstractFactory {
        <<interface>>
        +createProductA()
        +createProductB()
    }
    class ConcreteFactoryA {
        +createProductA()
        +createProductB()
    }
    class ConcreteFactoryB {
        +createProductA()
        +createProductB()
    }
    class ProductA {
        <<abstract>>
        +operationA()
    }
    class ProductA1 {
        +operationA()
    }
    class ProductA2 {
        +operationA()
    }
    class ProductB {
        <<abstract>>
        +operationB()
    }
    class ProductB1 {
        +operationB()
    }
    class ProductB2 {
        +operationB()
    }
    Client --> AbstractFactory : uses
    AbstractFactory <|-- ConcreteFactoryA : implements
    AbstractFactory <|-- ConcreteFactoryB : implements
    ConcreteFactoryA --> ProductA1 : creates
    ConcreteFactoryA --> ProductB1 : creates
    ConcreteFactoryB --> ProductA2 : creates
    ConcreteFactoryB --> ProductB2 : creates
    ProductA1 --|> ProductA : inherits
    ProductA2 --|> ProductA : inherits
    ProductB1 --|> ProductB : inherits
    ProductB2 --|> ProductB : inherits

通过上图所示的类图,我们可以看到客户端 Client 与具体的产品类 ProductA ProductB 之间,是通过工厂类 AbstractFactory 实现解耦的。具体的产品创建过程由 ConcreteFactoryA ConcreteFactoryB 实现,当需要新增产品或变更产品创建逻辑时,客户端代码无需改动,只需要修改或扩展相应的工厂实现即可。

4. 建造者模式与原型模式

4.1 建造者模式的原理与实现

4.1.1 构建复杂对象的过程封装

建造者模式(Builder Pattern)是一种对象构建型模式,主要用于创建复杂的对象。在建造者模式中,一个复杂对象的构建与它的表示分离,同样的构建过程可以创建不同的表示。建造者模式将一个复杂对象的构建过程细分为多个步骤,使得我们可以在创建对象的同时,不需要关心这些对象是如何组装的。

建造者模式的关键在于将产品的内部表象和产品的生成过程分割开来,使用一个导演类(Director)来管理建造过程,而具体如何建造则由具体建造者(Builder)来完成。

一个典型的建造者模式包含以下几个角色:

  • 产品角色(Product) :最终构建出来的复杂对象。
  • 建造者角色(Builder) :定义创建产品的接口,通常为一个抽象类。
  • 具体建造者角色(Concrete Builder) :实现Builder接口的具体类,构造和装配各个部件。
  • 指挥者角色(Director) :负责安排已有模块的顺序,然后告诉Builder开始建造。
  • 客户端(Client) :创建Director对象,并将Builder对象交给Director。
示例代码解析
// 产品角色
class Product {
    private String partA;
    private String partB;
    // ...其他部件

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

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

    // ...其他部件设置方法
}

// 抽象建造者
abstract class Builder {
    protected Product product = new Product();

    public abstract void buildPartA();
    public abstract void buildPartB();
    // ...其他部件构建方法

    public Product getResult() {
        return product;
    }
}

// 具体建造者
class ConcreteBuilder extends Builder {
    @Override
    public void buildPartA() {
        product.setPartA("构建部分A");
    }

    @Override
    public void buildPartB() {
        product.setPartB("构建部分B");
    }

    // ...其他部件构建实现
}

// 指挥者
class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public void construct() {
        builder.buildPartA();
        builder.buildPartB();
        // ...按顺序构建其他部分
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Builder builder = new ConcreteBuilder();
        Director director = new Director(builder);
        director.construct();
        Product product = builder.getResult();
        // 此时product已经构建完成
    }
}

在上面的代码示例中, Product 类代表了需要被构建的复杂对象。 Builder 是一个抽象类,定义了创建 Product 对象的各个步骤。 ConcreteBuilder 类继承自 Builder ,并实现了具体的构建过程。 Director 类负责按照顺序调用构建步骤。客户端代码中,我们创建了一个 ConcreteBuilder 对象和一个 Director 对象,然后通过 Director 对象指挥构建过程,最后得到一个完整的 Product 对象。

4.1.2 建造者模式的实例应用

实际开发案例

假设我们要构建一个Web页面生成器,页面包含标题、内容、页脚等部分。使用建造者模式可以让我们灵活地构建出不同样式的页面,而不需要修改现有代码。

// 页面产品角色
class WebPage {
    private String title;
    private String content;
    private String footer;

    public void setTitle(String title) {
        this.title = title;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public void setFooter(String footer) {
        this.footer = footer;
    }

    // ...toString方法等
}

// 页面建造者
abstract class PageBuilder {
    protected WebPage webPage = new WebPage();

    public abstract void buildTitle();
    public abstract void buildContent();
    public abstract void buildFooter();

    public WebPage getPage() {
        return webPage;
    }
}

// 具体页面建造者
class AboutPageBuilder extends PageBuilder {
    @Override
    public void buildTitle() {
        webPage.setTitle("关于我们");
    }

    @Override
    public void buildContent() {
        webPage.setContent("公司简介内容...");
    }

    @Override
    public void buildFooter() {
        webPage.setFooter("版权所有 © 公司名称");
    }
}

// 页面构建器
class PageBuilderDirector {
    public WebPage buildWebPage(PageBuilder builder) {
        builder.buildTitle();
        builder.buildContent();
        builder.buildFooter();
        return builder.getPage();
    }
}

// 客户端使用
public class WebPageBuilderClient {
    public static void main(String[] args) {
        PageBuilder builder = new AboutPageBuilder();
        PageBuilderDirector director = new PageBuilderDirector();
        WebPage page = director.buildWebPage(builder);
        System.out.println(page);
    }
}

在这个案例中, WebPage 类代表一个页面对象,包含了页面的标题、内容、页脚等属性。 PageBuilder 是一个抽象的页面建造者,定义了构建页面各个部分的方法。 AboutPageBuilder 类继承自 PageBuilder ,实现了构建一个具体页面的过程。 PageBuilderDirector 负责指挥构建过程,最后客户端代码通过调用 buildWebPage 方法,得到了一个完整的 WebPage 对象。

4.2 原型模式的实现方法与优势

克隆对象与性能优化

原型模式(Prototype Pattern)用于创建重复的对象,同时又能保证性能。这种模式实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建一个对象的代价比较大时,则采用这种模式。

原型模式允许一个对象再创建另外一个可定制的对象,无需知道如何创建的细节。工作原理是将一个原型对象传给要创建的对象,这个要创建的对象通过请求原型对象拷贝自己来实现创建过程。

原型模式通常包含以下角色:

  • 原型接口(Prototype) :用于声明克隆方法。
  • 具体原型类(Concrete Prototype) :实现克隆方法。
  • 客户端(Client) :让一个原型对象克隆自身从而创建一个新的对象。
示例代码解析
// 原型接口
interface Prototype {
    Prototype clone();
}

// 具体原型类
class ConcretePrototype implements Prototype {
    private String attribute;

    public void setAttribute(String attribute) {
        this.attribute = attribute;
    }

    public String getAttribute() {
        return this.attribute;
    }

    // 实现克隆方法
    @Override
    public ConcretePrototype clone() {
        ConcretePrototype clone = null;
        try {
            clone = (ConcretePrototype) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return clone;
    }
}

// 客户端代码
public class PrototypeClient {
    public static void main(String[] args) {
        ConcretePrototype prototype = new ConcretePrototype();
        prototype.setAttribute("属性值");
        // 使用克隆方法创建一个新的对象
        Prototype clone = prototype.clone();
        System.out.println(prototype.getAttribute());
        System.out.println(clone.getAttribute());
    }
}

在上面的例子中, Prototype 是一个接口,声明了 clone 方法。 ConcretePrototype 类实现了 Prototype 接口,同时重写了 clone 方法。客户端代码中,我们创建了一个 ConcretePrototype 对象,并通过调用 clone 方法来创建了一个新的对象。

原型模式通过克隆现有对象而不需要知道其内部结构来创建对象,这在很多场景中都可以提供性能优势,尤其是在创建大型对象或者复制对象时成本较高的情况下。同时,原型模式还可以帮助我们避免重复的初始化代码,使得代码更加简洁。

原型模式在实际开发中的应用案例

假设我们正在开发一个文档编辑器,其中需要复制各种文档对象(比如文本、图像、表格等)。使用原型模式,我们可以为每种文档对象创建原型接口,然后实现具体的复制逻辑。

// 文档对象原型接口
interface DocumentPrototype extends Prototype {
    void display();
}

// 文本对象
class TextDocument implements DocumentPrototype {
    private String text;

    public void setText(String text) {
        this.text = text;
    }

    @Override
    public void display() {
        System.out.println("显示文本内容: " + text);
    }

    // 具体克隆方法
    @Override
    public TextDocument clone() {
        TextDocument cloned = (TextDocument) super.clone();
        cloned.text = this.text;
        return cloned;
    }
}

// 图像对象
class ImageDocument implements DocumentPrototype {
    private String imagePath;

    public void setImagePath(String imagePath) {
        this.imagePath = imagePath;
    }

    @Override
    public void display() {
        System.out.println("显示图像路径: " + imagePath);
    }

    // 具体克隆方法
    @Override
    public ImageDocument clone() {
        ImageDocument cloned = (ImageDocument) super.clone();
        cloned.imagePath = this.imagePath;
        return cloned;
    }
}

// 客户端代码
public class DocumentPrototypeClient {
    public static void main(String[] args) {
        TextDocument textDoc = new TextDocument();
        textDoc.setText("这是一段文本。");

        ImageDocument imageDoc = new ImageDocument();
        imageDoc.setImagePath("路径到一张图片");

        DocumentPrototype textClone = textDoc.clone();
        DocumentPrototype imageClone = imageDoc.clone();

        textDoc.display();
        textClone.display();
        imageDoc.display();
        imageClone.display();
    }
}

在这个案例中,我们首先定义了一个 DocumentPrototype 接口,它继承自 Prototype 接口,并添加了一个 display 方法用于显示文档内容。 TextDocument ImageDocument 类实现了 DocumentPrototype 接口,并重写了 clone 方法来创建自身类型的克隆。客户端代码中创建了一个文本文档和一个图像文档的实例,并调用 clone 方法复制它们,然后展示每个文档的内容。

通过原型模式,我们在创建文档对象时无需关心对象是如何创建的,这使得代码更加简洁并且易于扩展。此外,当我们需要添加更多种类的文档对象时,可以轻松地实现它们的原型接口,并让客户端代码来利用这些新类型的文档对象。

5. 观察者模式至享元模式

5.1 观察者模式原理与实现

5.1.1 事件监听与响应机制

观察者模式,又称为发布-订阅模式,是一种在软件设计领域广泛使用的设计模式。它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会收到通知。这种模式常用于实现事件处理系统。

核心思想是将对象分为两部分:一部分是主体(Subject),负责维护状态和触发事件;另一部分是观察者(Observer),负责响应事件并更新状态。

代码示例:

import java.util.ArrayList;
import java.util.List;

interface Observer {
    void update(String message);
}

class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String state;

    @Override
    public void registerObserver(Observer o) {
        observers.add(o);
    }

    @Override
    public void removeObserver(Observer o) {
        observers.remove(o);
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(this.state);
        }
    }

    public void setState(String newState) {
        this.state = newState;
        notifyObservers();
    }
}

class ConcreteObserver implements Observer {
    @Override
    public void update(String message) {
        // 实现观察者的响应逻辑
        System.out.println("Received update: " + message);
    }
}

在上述代码中, Subject 接口定义了注册、移除和通知观察者的机制。 ConcreteSubject 类维护了一个观察者列表,并在状态改变时通知它们。 ConcreteObserver 类实现了观察者接口,定义了如何接收和处理通知。

5.1.2 观察者模式的典型应用实例

在实际应用中,观察者模式常用于图形用户界面(GUI)事件处理、消息分发、系统事件通知等场景。例如,在Android开发中,监听器模式实际上是观察者模式的另一种表述。

5.2 装饰器模式与代理模式

5.2.1 动态添加职责与控制访问

装饰器模式允许向一个现有的对象添加新的功能,同时又不改变其结构。它创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

代码示例:

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 ConcreteDecorator extends Decorator {
    public ConcreteDecorator(Component component) {
        super(component);
    }

    public void additionalBehavior() {
        System.out.println("Additional behavior");
    }

    @Override
    public void operation() {
        super.operation();
        additionalBehavior();
    }
}

在上面的代码示例中, Decorator 类通过一个抽象类来增强 Component ,而 ConcreteDecorator 实现了具体增强功能的类。

5.2.2 代理模式在系统中的作用

代理模式为其他对象提供一种代理以控制对这个对象的访问。代理模式在不改变原有对象代码的情况下,通过引入一个新的代理类来间接访问原有类的功能。

代码示例:

class Subject {
    public void request() {
        System.out.println("Subject: Handling request");
    }
}

class Proxy implements Subject {
    private Subject realSubject;

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

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

    private void postRequest() {
        System.out.println("Proxy: Post request");
    }
}

在这个例子中, Proxy 类模拟了一个网络请求的过程,它在实际调用请求方法前后分别添加了预处理和后处理的操作。

5.3 适配器模式与桥接模式

5.3.1 接口转换与解耦合

适配器模式允许将一个类的接口转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。

代码示例:

interface Target {
    void request();
}

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

class Adapter implements Target {
    private Adaptee adaptee = new Adaptee();

    @Override
    public void request() {
        adaptee.specificRequest();
    }
}

在这个实现中, Adapter 类将 Adaptee 类的特定请求方法适配成了 Target 接口的 request 方法。

5.3.2 桥接模式在系统设计中的应用

桥接模式将抽象部分与实现部分分离,使它们都可以独立地变化。它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。

代码示例:

abstract class Abstraction {
    protected Implementor implementor;

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

    public abstract void operation();
}

interface Implementor {
    void operationImpl();
}

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

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

    @Override
    public void operation() {
        implementor.operationImpl();
    }
}

在这个例子中, Abstraction 类通过 Implementor 接口与具体的实现类解耦,允许系统独立地变化。

5.4 组合模式与享元模式

5.4.1 处理复杂对象结构的设计模式

组合模式允许你将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

代码示例:

abstract class Component {
    protected String name;
    public Component(String name) { this.name = name; }
    public abstract void add(Component c);
    public abstract void remove(Component c);
    public abstract void display(int depth);
}

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

    public Composite(String name) { super(name); }

    @Override
    public void add(Component c) {
        children.add(c);
    }

    @Override
    public void remove(Component c) {
        children.remove(c);
    }

    @Override
    public void display(int depth) {
        System.out.println(new String(new char[depth]).replace('\0', '-') + name);
        for (Component component : children) {
            component.display(depth + 2);
        }
    }
}

class Leaf extends Component {
    public Leaf(String name) { super(name); }

    @Override
    public void add(Component c) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void remove(Component c) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void display(int depth) {
        System.out.println(new String(new char[depth]).replace('\0', '-') + name);
    }
}

在这个例子中, Composite 类代表容器节点,而 Leaf 类代表叶节点,二者都实现了 Component 接口,允许用户对树形结构进行统一操作。

5.4.2 优化资源使用与内存管理

享元模式是一种结构型设计模式,旨在通过共享已存在的相似对象减少内存使用,以支持大量细粒度的对象。

代码示例:

interface Flyweight {
    void operation(int extrinsicState);
}

class ConcreteFlyweight implements Flyweight {
    private int intrinsicState;

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

    public void operation(int extrinsicState) {
        System.out.println("Intrinsic State: " + intrinsicState + ", Extrinsic State: " + extrinsicState);
    }
}

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

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

在这个实现中, FlyweightFactory 类负责创建并管理享元对象,确保对相似对象的复用。享元模式通常用于创建大量细粒度对象的系统,例如文本编辑器中的字符对象。

通过上述示例代码,我们可以看到不同设计模式在代码实现上的差异与特点,每种模式都有其特定的适用场景和优势。在实际开发过程中,合理地运用这些模式能够显著提升代码的可读性、可维护性以及性能。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:设计模式是软件工程中的最佳实践,提供了一套可重用的解决方案模板,用于解决开发中常见的问题。本PPT合集详尽介绍了各种设计模式,包括单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式、观察者模式、装饰器模式、代理模式、适配器模式、桥接模式、组合模式、享元模式、状态模式、策略模式和模板方法模式。这些模式有助于编写灵活和可维护的代码,并适合初学者学习和理解。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值