30天学会Java-29:设计模式(二)

1. 代理模式(Proxy Pattern)

1.1 概述

代理模式是一种结构型设计模式,它为另一个对象提供一个替身或占位符,以控制对这个对象的访问。代理对象可以在客户端和目标对象之间插入额外的逻辑,例如访问控制、日志记录、性能监控、远程调用等。

1.2 角色

  • Subject(抽象主题):定义了 RealSubject 和 Proxy 的共同接口,这样在任何使用 RealSubject 的地方都可以使用 Proxy。
  • RealSubject(真实主题):定义了代理对象所代表的真实对象。
  • Proxy(代理):持有对真实主题的引用,并实现与真实主题相同的接口,以便在客户端和真实主题之间进行操作。

1.3 实现

1.3.1 静态代理

代理类在编译时就已经存在,通常由开发者手动创建。

// 抽象主题接口
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 StaticProxyDemo {
    public static void main(String[] args) {
        Subject proxy = new Proxy();
        proxy.request();
    }
}
1.3.2 动态代理

代理类在运行时动态生成,通常使用 Java 的反射机制(java.lang.reflect.Proxyjava.lang.reflect.InvocationHandler)或第三方库(如 CGLIB)。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 抽象主题接口 (同上)
// interface Subject { void request(); }

// 真实主题类 (同上)
// class RealSubject implements Subject { ... }

// 动态代理处理器
class DynamicProxyHandler implements InvocationHandler {
    private Object target; // 真实主题对象

    public DynamicProxyHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("DynamicProxy: Pre-processing request for method: " + method.getName());
        // 调用真实主题的方法
        Object result = method.invoke(target, args);
        System.out.println("DynamicProxy: Post-processing request for method: " + method.getName());
        return result;
    }
}

// 使用示例
public class DynamicProxyDemo {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();

        // 创建动态代理实例
        Subject proxy = (Subject) Proxy.newProxyInstance(
                realSubject.getClass().getClassLoader(), // 类加载器
                realSubject.getClass().getInterfaces(),   // 真实主题实现的接口
                new DynamicProxyHandler(realSubject)      // 代理处理器
        );

        proxy.request();
    }
}

2. 装饰器模式(Decorator Pattern)

2.1 概述

装饰器模式是一种结构型设计模式,它允许在不改变原有对象结构的情况下,动态地给对象添加新的功能。它比继承更加灵活,可以避免继承体系的臃肿。

2.2 角色

  • Component(抽象组件):定义一个对象接口,可以给这些对象动态地添加职责。
  • ConcreteComponent(具体组件):定义一个将要被装饰的原始对象。
  • Decorator(抽象装饰器):持有一个 Component 对象的引用,并实现 Component 接口。
  • ConcreteDecorator(具体装饰器):实现抽象装饰器,向组件添加新的职责。

2.3 实现

// 抽象组件接口
interface Coffee {
    String getDescription();
    double getCost();
}

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

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

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

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

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

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

// 具体装饰器:加牛奶
class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee decoratedCoffee) {
        super(decoratedCoffee);
    }

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

    @Override
    public double getCost() {
        return super.getCost() + 1.5;
    }
}

// 具体装饰器:加糖
class SugarDecorator extends CoffeeDecorator {
    public SugarDecorator(Coffee decoratedCoffee) {
        super(decoratedCoffee);
    }

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

    @Override
    public double getCost() {
        return super.getCost() + 0.5;
    }
}

// 使用示例
public class DecoratorPatternDemo {
    public static void main(String[] args) {
        // 一杯简单的咖啡
        Coffee coffee = new SimpleCoffee();
        System.out.println("Description: " + coffee.getDescription() + ", Cost: " + coffee.getCost());

        // 加牛奶的咖啡
        Coffee milkCoffee = new MilkDecorator(new SimpleCoffee());
        System.out.println("Description: " + milkCoffee.getDescription() + ", Cost: " + milkCoffee.getCost());

        // 加牛奶和糖的咖啡
        Coffee milkAndSugarCoffee = new SugarDecorator(new MilkDecorator(new SimpleCoffee()));
        System.out.println("Description: " + milkAndSugarCoffee.getDescription() + ", Cost: " + milkAndSugarCoffee.getCost());
    }
}

3. 策略模式(Strategy Pattern)

3.1 概述

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

3.2 角色

  • Strategy(抽象策略):定义所有支持的算法的公共接口。
  • ConcreteStrategy(具体策略):实现抽象策略接口,提供具体的算法实现。
  • Context(上下文):持有一个对抽象策略对象的引用,并提供一个接口,允许客户端设置和切换策略。

3.3 实现

// 抽象策略接口
interface PaymentStrategy {
    void pay(double amount);
}

// 具体策略:信用卡支付
class CreditCardPayment implements PaymentStrategy {
    private String cardNumber;
    private String name;

    public CreditCardPayment(String cardNumber, String name) {
        this.cardNumber = cardNumber;
        this.name = name;
    }

    @Override
    public void pay(double amount) {
        System.out.println(amount + " paid with credit card: " + cardNumber + " (Holder: " + name + ")");
    }
}

// 具体策略:PayPal 支付
class PaypalPayment implements PaymentStrategy {
    private String emailId;

    public PaypalPayment(String emailId) {
        this.emailId = emailId;
    }

    @Override
    public void pay(double amount) {
        System.out.println(amount + " paid using Paypal: " + emailId);
    }
}

// 上下文类
class ShoppingCart {
    private PaymentStrategy paymentStrategy;

    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }

    public void checkout(double amount) {
        if (paymentStrategy == null) {
            System.out.println("Please select a payment strategy.");
            return;
        }
        paymentStrategy.pay(amount);
    }
}

// 使用示例
public class StrategyPatternDemo {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();

        // 使用信用卡支付
        cart.setPaymentStrategy(new CreditCardPayment("1234-5678-9012-3456", "John Doe"));
        cart.checkout(100.0);

        // 使用 PayPal 支付
        cart.setPaymentStrategy(new PaypalPayment("john.doe@example.com"));
        cart.checkout(50.0);
    }
}

总结

本节继续介绍了三种常用的设计模式:

  • 代理模式:为另一个对象提供一个替身,以控制对这个对象的访问,并可以在访问前后添加额外逻辑。
  • 装饰器模式:在不改变原有对象结构的情况下,动态地给对象添加新的功能,比继承更灵活。
  • 策略模式:定义一系列算法,将每个算法封装起来,并使它们可以相互替换,让算法独立于使用它的客户端而变化。

掌握这些设计模式能够帮助你更好地组织代码,提高代码的复用性、可维护性和扩展性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明似水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值