设计模式概述 - 简单工厂 & 策略 & 装饰器 & 代理
简单工厂模式简述
简单工厂模式(Simple Factory Pattern)是一种创建对象的设计模式,属于创建型模式。它通过一个工厂类来创建不同类型的对象,而不需要在客户端代码中直接使用 new
关键字。这样可以将对象的创建和使用分离,提高代码的灵活性和可维护性。
主要角色
- 工厂类:负责创建产品对象。
- 产品接口:定义产品的基本行为。
- 具体产品:实现产品接口的具体类。
优点
- 降低耦合:客户端代码不需要关心具体的产品类,只需要依赖于产品接口。
- 易于扩展:增加新产品时只需创建新的具体产品类和更新工厂类。
缺点
- 违反开闭原则:每次增加新产品时需要修改工厂类。
- 工厂类职责过重:工厂类可能会变得复杂,承担过多的责任。
示例代码(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)是一种行为型设计模式,它定义了一系列算法,将每个算法封装起来,并使它们可以互换。策略模式使得算法的变化独立于使用算法的客户。
主要角色
- 上下文(Context):持有一个策略类的引用,并且可以在运行时切换策略。
- 策略接口(Strategy):定义一个公共接口,所有具体策略类都要实现这个接口。
- 具体策略(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)是一种结构型设计模式,允许用户在不改变对象结构的情况下,动态地添加功能。该模式通过创建一个装饰类来包装原有类,从而提供额外的功能。
主要角色
组件(Component):
- 定义一个接口,用于实现对象和装饰器的共同接口。
具体组件(ConcreteComponent):
- 实现了组件接口的具体类,表示被装饰的对象。
装饰器(Decorator):
- 也是实现了组件接口的抽象类,持有一个组件对象的引用,用于在其上添加额外的功能。
具体装饰器(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)是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。代理模式通常用于以下几种情况:
- 保护代理:控制对真实对象的访问,以保护真实对象。
- 虚代理:延迟加载真实对象,直到需要使用它时才创建。
- 远程代理:为远程对象提供一个本地代理,以便在本地调用远程对象的方法。
角色
- 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();
}
}