设计模式-简单工厂&策略&装饰器&代理

发布于:2025-09-10 ⋅ 阅读:(20) ⋅ 点赞:(0)

设计模式概述 - 简单工厂 & 策略 & 装饰器 & 代理

简单工厂模式简述

简单工厂模式(Simple Factory Pattern)是一种创建对象的设计模式,属于创建型模式。它通过一个工厂类来创建不同类型的对象,而不需要在客户端代码中直接使用 new 关键字。这样可以将对象的创建和使用分离,提高代码的灵活性和可维护性。

主要角色

  1. 工厂类:负责创建产品对象。
  2. 产品接口:定义产品的基本行为。
  3. 具体产品:实现产品接口的具体类。

优点

  • 降低耦合:客户端代码不需要关心具体的产品类,只需要依赖于产品接口。
  • 易于扩展:增加新产品时只需创建新的具体产品类和更新工厂类。

缺点

  • 违反开闭原则:每次增加新产品时需要修改工厂类。
  • 工厂类职责过重:工厂类可能会变得复杂,承担过多的责任。

示例代码(Java)

// 产品接口
interface Product {
    void use();
}

// 具体产品A
class ConcreteProductA implements Product {
    @Override
    public void use() {
        System.out.println("使用产品A");
    }
}

// 具体产品B
class ConcreteProductB implements Product {
    @Override
    public void use() {
        System.out.println("使用产品B");
    }
}

// 工厂类
class SimpleFactory {
    public static Product createProduct(String type) {
        switch (type) {
            case "A":
                return new ConcreteProductA();
            case "B":
                return new ConcreteProductB();
            default:
                throw new IllegalArgumentException("未知产品类型");
        }
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Product productA = SimpleFactory.createProduct("A");
        productA.use();

        Product productB = SimpleFactory.createProduct("B");
        productB.use();
    }
}

策略模式简述

策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,将每个算法封装起来,并使它们可以互换。策略模式使得算法的变化独立于使用算法的客户。

主要角色

  1. 上下文(Context):持有一个策略类的引用,并且可以在运行时切换策略。
  2. 策略接口(Strategy):定义一个公共接口,所有具体策略类都要实现这个接口。
  3. 具体策略(ConcreteStrategy):实现策略接口的具体算法。

优点

  • 开放/封闭原则:可以在不修改上下文的情况下添加新策略。
  • 避免使用多重条件语句:通过策略模式可以消除复杂的条件语句。

缺点

  • 客户端需要知道所有的策略:客户端需要了解所有可用的策略。
  • 增加了对象的数量:每个策略都需要一个具体的类,可能会增加系统的复杂性。

示例代码(Java)

// 策略接口
interface Strategy {
    int doOperation(int num1, int num2);
}

// 具体策略A
class Addition implements Strategy {
    @Override
    public int doOperation(int num1, int num2) {
        return num1 + num2;
    }
}

// 具体策略B
class Subtraction implements Strategy {
    @Override
    public int doOperation(int num1, int num2) {
        return num1 - num2;
    }
}

// 具体策略C
class Multiplication implements Strategy {
    @Override
    public int doOperation(int num1, int num2) {
        return num1 * num2;
    }
}

// 上下文
class Context {
    private Strategy strategy;

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

    public int executeStrategy(int num1, int num2) {
        return strategy.doOperation(num1, num2);
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Context context = new Context();

        // 使用加法策略
        context.setStrategy(new Addition());
        System.out.println("10 + 5 = " + context.executeStrategy(10, 5));

        // 使用减法策略
        context.setStrategy(new Subtraction());
        System.out.println("10 - 5 = " + context.executeStrategy(10, 5));

        // 使用乘法策略
        context.setStrategy(new Multiplication());
        System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
    }
}

装饰器模式简述

装饰器模式(Decorator Pattern)是一种结构型设计模式,允许用户在不改变对象结构的情况下,动态地添加功能。该模式通过创建一个装饰类来包装原有类,从而提供额外的功能。

主要角色

  1. 组件(Component)

    • 定义一个接口,用于实现对象和装饰器的共同接口。
  2. 具体组件(ConcreteComponent)

    • 实现了组件接口的具体类,表示被装饰的对象。
  3. 装饰器(Decorator)

    • 也是实现了组件接口的抽象类,持有一个组件对象的引用,用于在其上添加额外的功能。
  4. 具体装饰器(ConcreteDecorator)

    • 继承自装饰器类,提供具体的装饰功能。

示例代码

// 组件接口
interface Coffee {
    String getDescription();
    double cost();
}

// 具体组件
class SimpleCoffee implements Coffee {
    @Override
    public String getDescription() {
        return "Simple Coffee";
    }

    @Override
    public double cost() {
        return 5.0;
    }
}

// 装饰器抽象类
abstract class CoffeeDecorator implements Coffee {
    protected Coffee decoratedCoffee;

    public CoffeeDecorator(Coffee coffee) {
        this.decoratedCoffee = coffee;
    }

    @Override
    public String getDescription() {
        return decoratedCoffee.getDescription();
    }

    @Override
    public double cost() {
        return decoratedCoffee.cost();
    }
}

// 具体装饰器
class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        return decoratedCoffee.getDescription() + ", Milk";
    }

    @Override
    public double cost() {
        return decoratedCoffee.cost() + 1.5;
    }
}

// 具体装饰器
class SugarDecorator extends CoffeeDecorator {
    public SugarDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        return decoratedCoffee.getDescription() + ", Sugar";
    }

    @Override
    public double cost() {
        return decoratedCoffee.cost() + 0.5;
    }
}

// 使用示例
public class DecoratorPatternExample {
    public static void main(String[] args) {
        Coffee coffee = new SimpleCoffee();
        System.out.println(coffee.getDescription() + " $" + coffee.cost());

        coffee = new MilkDecorator(coffee);
        System.out.println(coffee.getDescription() + " $" + coffee.cost());

        coffee = new SugarDecorator(coffee);
        System.out.println(coffee.getDescription() + " $" + coffee.cost());
    }
}

代理模式简述

代理模式(Proxy Pattern)是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。代理模式通常用于以下几种情况:

  1. 保护代理:控制对真实对象的访问,以保护真实对象。
  2. 虚代理:延迟加载真实对象,直到需要使用它时才创建。
  3. 远程代理:为远程对象提供一个本地代理,以便在本地调用远程对象的方法。

角色

  • Subject:定义真实对象和代理对象的共同接口。
  • RealSubject:实现了Subject接口的真实对象。
  • Proxy:实现了Subject接口,持有对RealSubject的引用,并控制对其的访问。

优点

  • 控制访问:可以控制对真实对象的访问。
  • 延迟加载:可以在需要时才创建真实对象,节省资源。
  • 增强功能:可以在调用真实对象的方法前后添加额外的功能。

缺点

  • 增加复杂性:引入代理对象会增加系统的复杂性。
  • 性能开销:代理对象可能会引入额外的性能开销。

示例代码

// Subject接口
interface Subject {
    void request();
}

// 真实对象
class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("RealSubject: Handling request.");
    }
}

// 代理对象
class Proxy implements Subject {
    private RealSubject realSubject;

    @Override
    public void request() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        // 在调用真实对象的方法之前可以添加额外的逻辑
        System.out.println("Proxy: Pre-processing request.");
        realSubject.request();
        // 在调用真实对象的方法之后可以添加额外的逻辑
        System.out.println("Proxy: Post-processing request.");
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Subject proxy = new Proxy();
        proxy.request();
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到