计划模式入门:从 GoF 分类到 SOLID 原则实战

打印 上一主题 下一主题

主题 1708|帖子 1708|积分 5128

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
计划模式入门:从 GoF 分类到 SOLID 原则实战

一、计划模式的劈头与焦点价值

1.1 为什么必要计划模式?

在软件开发中,重复解决相似问题会导致:


  • 代码冗余:雷同逻辑重复实现(如日志模块)
  • 维护困难:修改一处影响多处(如硬编码策略)
  • 扩展性差:新增功能需大幅改动现有代码
计划模式通过可复用的解决方案模板,资助开发者:

  • 提拔代码可维护性(遵照开闭原则)
  • 低沉模块耦合度(依赖倒置原则)
  • 加速计划决策(直接应用成熟方案)
1.2 GoF 23 种模式分类

1994 年《计划模式:可复用面向对象软件的底子》提出经典分类,形成计划模式的 “瑞士军刀”:
     二、面向对象计划五大焦点原则(SOLID)

2.1 单一职责原则(SRP)

定义:一个类只负责一项职责反例
  1. // 反模式:同时处理用户认证和日志记录  
  2. public class UserService {  
  3.     public boolean login(String username, String password) {  
  4.         // 认证逻辑  
  5.         log("用户登录:" + username);  
  6.         return true;  
  7.     }  
  8.     private void log(String msg) {  
  9.         // 日志写入文件  
  10.     }  
  11. }  
复制代码
重构
  1. // 拆分认证服务与日志服务  
  2. public class UserAuthService { /* 认证逻辑 */ }  
  3. public class LoggerService { /* 日志写入 */ }  
复制代码
2.2 开闭原则(OCP)

定义:对扩展开放,对修改关闭实现方式

  • 通过接口定义举动(Logger接口)
  • 详细实现类继承接口(FileLogger, ConsoleLogger)
  • 客户端依赖接口而非实现
实战
  1. // 定义日志接口  
  2. public interface Logger {  
  3.     void log(String message);  
  4. }  
  5. // 扩展实现(无需修改原有代码)  
  6. public class FileLogger implements Logger { /* 文件日志 */ }  
  7. public class ConsoleLogger implements Logger { /* 控制台日志 */ }  
  8. // 客户端注入接口(Spring依赖注入)  
  9. @Service  
  10. public class OrderService {  
  11.     private final Logger logger;  
  12.     public OrderService(Logger logger) { this.logger = logger; }  
  13. }  
复制代码
2.3 依赖倒置原则(DIP)

定义:高层模块不依赖低层模块,共同依赖抽象错误实践
  1. // 高层模块直接依赖具体实现(数据库操作)  
  2. public class UserRepository {  
  3.     private MySQLConnection conn; // 低层模块  
  4. }  
复制代码
精确实践
  1. // 定义抽象接口  
  2. public interface DatabaseConnection { /* 数据库连接 */ }  
  3. // 具体实现(MySQL/Oracle)  
  4. public class MySQLConnection implements DatabaseConnection { /* ... */ }  
  5. // 高层模块依赖抽象  
  6. public class UserRepository {  
  7.     private final DatabaseConnection conn;  
  8.     public UserRepository(DatabaseConnection conn) { this.conn = conn; }  
  9. }  
复制代码
2.4 里氏替换原则(LSP)

定义:子类可替换父类而不影响程序逻辑案例
  1. // 正方形不应继承长方形(违反面积计算逻辑)  
  2. class Rectangle {  
  3.     protected int width, height;  
  4.     public void setWidth(int w) { width = w; }  
  5.     public void setHeight(int h) { height = h; }  
  6. }  
  7. // 反模式:正方形强制要求width=height  
  8. class Square extends Rectangle {  
  9.     @Override  
  10.     public void setWidth(int w) {  
  11.         width = w;  
  12.         height = w; // 破坏里氏替换原则  
  13.     }  
  14. }  
复制代码
2.5 接口隔离原则(ISP)

定义:客户端不依赖不必要的接口方法反模式
  1. // 胖接口包含无关方法  
  2. public interface Animal {  
  3.     void eat();  
  4.     void fly(); // 非所有动物都会飞  
  5. }  
  6. class Pig implements Animal {  
  7.     @Override public void eat() { /* ... */ }  
  8.     @Override public void fly() { throw new UnsupportedOperationException(); } // 强制实现无用方法  
  9. }  
复制代码
重构
  1. // 拆分为独立接口  
  2. public interface EatAble { void eat(); }  
  3. public interface FlyAble { void fly(); }  
  4. class Pig implements EatAble { /* 仅实现进食 */ }  
  5. class Bird implements EatAble, FlyAble { /* 实现两种能力 */ }  
复制代码
三、计划模式在 Java 生态中的典范应用

3.1 JDK 中的模式实践

模式JDK 类 / 方法应用场景工厂模式Calendar.getInstance()创建差别时区的日历实例单例模式Runtime.getRuntime()全局唯一运行时环境观察者模式Observable/ObserverAWT 事件监听机制 3.2 Spring 框架中的模式应用


  • 工厂模式
  1. // BeanFactory创建Bean实例  
  2. ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");  
  3. UserService userService = context.getBean("userService", UserService.class);  
复制代码

  • 署理模式
  1. // AOP实现方法增强  
  2. @Transactional  
  3. public void createOrder() { /* 订单创建 */ }  
复制代码

  • 模板方法
  1. // JdbcTemplate简化数据库操作  
  2. jdbcTemplate.query("SELECT * FROM USER", (rs) -> new User(rs.getInt("id")));  
复制代码
3.3 Spring 框架深度模式解析

3.3.1 装饰器模式(Decorator Pattern)

框架应用


  • BeanPostProcessor:加强 Bean 功能(如 AOP 署理生成)
  • HandlerInterceptor:哀求处理链加强(日志记载、权限校验)
源码解析
  1. // BeanPostProcessor装饰器链  
  2. public interface BeanPostProcessor {  
  3.     Object postProcessBeforeInitialization(Object bean, String beanName);  
  4.     Object postProcessAfterInitialization(Object bean, String beanName);  
  5. }  
  6. // 典型实现:ProxyProcessorSupport(生成AOP代理)  
  7. protected Object postProcessAfterInitialization(Object bean, String beanName) {  
  8.     if (!this.targetSourcedBeans.contains(beanName)) {  
  9.         return createProxy(bean, beanName, specificInterceptors, new SingletonTargetSource(bean));  
  10.     }  
  11.     return bean;  
  12. }  
复制代码
3.3.2 策略模式(Strategy Pattern)

应用场景


  • 事务管理策略:PlatformTransactionManager支持差别事务源(JTA/DataSource)
  • 消息转换器:HttpMessageConverter支持多种数据格式(JSON/XML)
配置示例
  1. // 声明不同事务策略  
  2. @Bean  
  3. public PlatformTransactionManager jtaTransactionManager() {  
  4.     return new JtaTransactionManager();  
  5. }  
  6. @Bean  
  7. public PlatformTransactionManager dataSourceTransactionManager(DataSource dataSource) {  
  8.     return new DataSourceTransactionManager(dataSource);  
  9. }  
  10. // 根据环境选择策略  
  11. @Service  
  12. public class OrderService {  
  13.     @Autowired  
  14.     private PlatformTransactionManager transactionManager;  
  15. }  
复制代码
3.3.3 责任链模式(Chain of Responsibility Pattern)

焦点实现


  • Filter 链:DispatcherServlet处理哀求的过滤器链(DelegatingFilterProxy)
  • 异常处理链:HandlerExceptionResolver处理差别类型异常
哀求处理流程
     3.4 Spring Boot 自动配置中的模式应用

3.4.1 工厂模式(Factory Pattern)

自动配置原理


  • EnableAutoConfiguration通过AutoConfigurationImportSelector加载配置类
  • @ConditionalOnMissingBean避免重复创建 Bean
案例:数据库连接池自动配置
  1. // DataSourceAutoConfiguration  
  2. @Bean  
  3. @ConditionalOnMissingBean  
  4. public DataSource dataSource(DataSourceProperties properties) {  
  5.     return properties.initializeDataSourceBuilder().type(this::getDataSourceType).build();  
  6. }  
复制代码
3.4.2 模板方法(Template Method)

焦点抽象类


  • AbstractApplicationContext:模板方法refresh()定义容器启动流程
  • RepositoryRestConfigurer:提供扩展点供用户自定义
容器启动模板
  1. public abstract class AbstractApplicationContext extends DefaultResourceLoader  
  2.         implements ConfigurableApplicationContext {  
  3.     @Override  
  4.     public void refresh() throws BeansException, IllegalStateException {  
  5.         synchronized (this.startupShutdownMonitor) {  
  6.             prepareRefresh();  
  7.             ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();  
  8.             prepareBeanFactory(beanFactory);  
  9.             // 模板方法扩展点  
  10.             onRefresh();  
  11.         }  
  12.     }  
  13.     protected void onRefresh() { /* 子类实现 */ }  
  14. }  
复制代码
3.5 Spring Cloud 中的模式实践

3.5.1 署理模式(Proxy Pattern)

OpenFeign 远程调用


  • 通过动态署理生成 HTTP 客户端
  • 整合 Ribbon 负载均衡与 Sentinel 熔断
署理生成逻辑
  1. // FeignClientFactoryBean  
  2. public Object getObject() throws Exception {  
  3.     return getTarget();  
  4. }  
  5. <T> T getTarget() {  
  6.     FeignContext context = applicationContext.getBean(FeignContext.class);  
  7.     Feign.Builder builder = feign(context);  
  8.     // 生成代理对象  
  9.     return (T) builder.target(type, getUrl());  
  10. }  
复制代码
3.5.2 责任链模式(Filter Chain)

Spring Cloud Gateway


  • 路由过滤器链实现哀求转换(鉴权 / 限流 / 参数校验)
  • 支持自定义过滤器顺序(Ordered接口)
配置示例
  1. spring:  
  2.   cloud:  
  3.     gateway:  
  4.       routes:  
  5.       - id: order-service  
  6.         uri: lb://order-service  
  7.         predicates:  
  8.         - Path=/api/order/**  
  9.         filters:  
  10.         - name: RequestRateLimiter  
  11.           args:  
  12.             key-resolver: "#{@ipKeyResolver}"  
  13.         - name: HeaderFilter  
  14.           args:  
  15.             request-headers-to-add:  
  16.               - name: X-Request-Id  
  17.                 value: "#{UUID.randomUUID().toString()}"  
复制代码
四、企业级框架模式应用对比(新增章节)

4.1 主流框架模式使用频率统计

模式类型Spring FrameworkSpring BootSpring CloudMyBatis工厂模式★★★★☆★★★★★★★★★☆★★★☆☆署理模式★★★★★★★★☆☆★★★★★★★★★☆模板方法★★★☆☆★★★☆☆★★☆☆☆★★★★☆责任链模式★★★☆☆★★☆☆☆★★★★☆★★☆☆☆ 4.2 模式选择决策树(Spring 场景)

     4.3 常见误区


  • 过度计划:简单场景滥用模式(如单例用于无状态工具类)
  • 忽视原则:优先满足模式结构而违反 SOLID 原则
  • 脱离场景:不联合业务需求选择模式(如用工厂模式处理简单对象创建)
五、模式应用最佳实践(Spring 场景)

5.1 避免模式误用的三个原则


  • 优先原则而非模式:先满足 SOLID 原则,再考虑模式实现

    • 反例:为使用工厂模式而强行拆分简单类

  • 联合框架特性:利用 Spring 现有模式扩展点(如@Conditional替换硬编码条件判断)
  • 控制复杂度:单个类模式应用不高出 2 种(避免过度计划)
5.2 模式组合使用案例

场景:实现可扩展的日志系统

  • 工厂模式:创建差别日志处理器(文件 / 数据库 / 控制台)
  • 策略模式:动态切换日志级别(DEBUG/INFO/ERROR)
  • 装饰器模式:为日志处理器添加加密 / 压缩功能
实现架构
  1. // 工厂创建策略实例  
  2. LoggerFactory.getLogger(Strategy.LOCAL_FILE);  
  3. // 装饰器增强功能  
  4. Logger logger = new EncryptDecorator(new CompressDecorator(logger));  
复制代码
通过补充 Spring 及扩展框架中的模式应用,开发者能更深入理解计划模式在现实框架中的落地方式。这些案例不但展示了模式的详细实现,更表现了如何通过模式组合解决复杂问题。下一篇我们将进入创建型模式专题,详细解析单例模式的线程安全实现与工厂模式的扩展应用。


   计划模式的焦点不是影象 23 种模板,而是培养 “识别问题→匹配方案→验证原则” 的思维方式:
  

  • 识别重复问题:发当代码中相似的计划痛点(如硬编码策略)
  • 匹配成熟方案:从模式库中选择最适合的解决方案(如策略模式替换大量条件判断)
  • 验证计划原则:确保实现符合 SOLID 原则(如依赖倒置保证扩展性)
    通事后续系列博客,我们将深入每种模式的实现细节,并联合 Spring、微服务等实战场景,演示如何用模式思维解决复杂系统计划问题。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

东湖之滨

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表