演示工厂模式和策略模式的基本用法
一、工厂模式(枚举+反射)
工厂模式将对象的创建逻辑与使用逻辑解耦,上层无需直接new具体类,直接通过工厂即可获取实例。当前演示简单的工厂模式,通过枚举约束类型 + 反射创建实例,完美遵循开闭原则(新增实现类仅新增代码,无需修改原有代码)。
工厂模式模块包含四个核心部分:
- 枚举类(TypeEnum.java):从编译期约束类型(杜绝传入非法类型),同时绑定类型与实现类,并提供反射创建实例的能力;解决简单工厂违背开闭原则的关键,新增实现时,仅需新增枚举项和实现类,无需修改原有代码。通过泛型约束,保证反射创建的实例一定是AbstractA的子类,类型安全。
java
public enum TypeEnum {
A1(A1Impl.class),
A2(A2Impl.class);
private final Class<? extends AbstractA> clazz;
TypeEnum(Class<? extends AbstractA> clazz) {
this.clazz = clazz;
}
public AbstractA createInstance() {
try {
return clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
- 工厂类(Factory.java,纯入口转发器,彻底解耦)。作为统一的实例创建入口,上层代码仅需与Factory交互,无需直接操作枚举,符合 "单一入口"的设计思想;工厂类的代码极简且永不修改,仅做 "转发器",彻底与具体实现类解耦,这是开闭原则的重要保障。
java
public class Factory {
private Factory() {
}
public static AbstractA createInstance(TypeEnum type) {
return type.createInstance();
}
}
- 抽象产品类(AbstractA.java):定义所有具体实现类的统一接口规范,是 "面向抽象编程"的基础;工厂模式的抽象产品,所有产品都要集成并实现抽象方法,定义一些公共的属性。
java
public abstract class AbstractA {
public abstract void run();
}
- 具体实现(A1Impl.java , A2Impl.java, ...):继承抽象类AbstractA并实现抽象方法,封装具体的实现业务逻辑。
java
public class A1Impl extends AbstractA {
@Override
public void run() {
System.out.println(" === >> :: A1Impl");
}
}
public class A2Impl extends AbstractA {
@Override
public void run() {
System.out.println(" === >> :: A2Impl");
}
}
演示
工厂模式的上层调用方式,全程面向抽象(AbstractA)编程,完全不感知具体实现类,如需切换仅需修改参数,不动代码实现。
java
public class Main {
public static void main(String[] args) {
// 切换仅需修改参数:TypeEnum.A2
AbstractA factory = Factory.createInstance(TypeEnum.A1);
factory.run();
}
}
// === >> :: A1Impl
二、策略模式(抽象类封装公共逻辑,动态切换策略)
策略模式的核心作用是将不同的算法/行为封装为独立的策略类,让策略可以在运行时动态切换,上层代码无需感知策略的具体实现;本版通过提取抽象策略类,消除了具体策略类的代码重复
策略模式模块包含四个核心部分:
- 策略的管理者和执行器(Context.java):封装策略的执行流程,作为策略与上层代码的中间层,上层代码无需直接调用策略的run方法,仅需调用上下文的start方法。如果后续需要给策略执行增加前置/后置逻辑(如参数校验、执行日志),仅需修改start方法,所有策略的执行都会统一生效,无需修改每个策略类。
java
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Context {
private Strategy strategy;
public void start() {
this.strategy.run();
}
}
- 策略顶层接口(Strategy.java):定义所有策略的统一规范,是 "面向接口编程" 的基础,保证所有策略都有统一的执行入口,是所有具体策略的"契约"。
java
public interface Strategy {
void run();
}
- 抽象策略类(AbstractStrategy.java):封装所有具体策略的公共字段和逻辑,消除代码重复,新增具体策略时,仅需继承该抽象类,实现run方法即可,无需重复编写公共的字段和构造器,大幅提升开发效率。
java
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
public abstract class AbstractStrategy implements Strategy {
protected String name;
protected int age;
public AbstractStrategy(String name, int age) {
this.name = name;
this.age = age;
}
}
- 具体策略类(BStrategyImpl.java , B2StrategyImpl.java, ...):封装具体的策略逻辑。子类的代码极简,仅需关注差异化逻辑(run方法),公共逻辑全部继承自抽象类,符合 "单一职责原则"。
java
public class BStrategyImpl extends AbstractStrategy {
public BStrategyImpl(String name, int age) {
super(name, age);
}
@Override
public void run() {
System.out.println("BStrategyImpl:我是:" + this.name + ", 今年:" + this.age);
}
}
public class B2StrategyImpl extends AbstractStrategy {
public B2StrategyImpl(String name, int age) {
super(name, age);
}
@Override
public void run() {
System.out.println("B2StrategyImpl:我是:" + this.name + ", 今年:" + this.age);
}
}
演示
演示策略模式的上层调用方式,体现 "策略动态切换" 的核心优势;切换策略时,仅需调用setStrategy方法传入新策略,上下文(Context)和上层代码无需任何其他修改,符合"对扩展开放,对修改关闭"。
java
public class Main {
public static void main(String[] args) {
Context context = new Context();
Strategy strategy1 = new BStrategyImpl("张三", 18);
context.setStrategy(strategy1);
context.start();
Strategy strategy2 = new B2StrategyImpl("李四", 28);
context.setStrategy(strategy2);
context.start();
}
}
// BStrategyImpl:我是:张三, 今年:18
// B2StrategyImpl:我是:李四, 今年:28
总结:以上实现能让新手快速理解工厂模式和策略模式的基础用法和核心思想,代码简洁、可运行、无冗余业务逻辑。