第六次博客作业:软件设计笔记--拒绝“万能类”,从 CRM 图表到系统登录的重构思考

前言

课堂上,老师展示了两个非常典型的反面教材:一个是 Sunny 软件公司的 CRM 图表显示系统,另一个是基于 Java C/S 系统的登录功能。这两个案例虽然业务场景不同,但都指向了软件设计中两个最核心的痛点:如何面对变化(开闭原则)以及如何界定责任(单一职责原则)。

  1. 应对变化:CRM 图表系统的重构之路

在第一个案例中,Sunny 公司开发了一个 CRM 系统,需要显示饼状图(PieChart)和柱状图(BarChart)。原始的设计方案如图所示:有一个  ChartDisplay  类,里面有一个  display(String type)  方法。

这种设计严重违反了开闭原则。
若我们要加一个折线图(LineChart)。”按照原来的写法,我们必须修改  ChartDisplay  类的源代码,在  display  方法里增加一个  if (type.equals("line"))  的判断分支。

重构方案:多态与抽象
为了符合“对扩展开放,对修改关闭”的原则,我们需要引入抽象。

我们可以定义一个抽象的图表接口或父类  AbstractChart ,其中包含一个抽象方法  display() 。然后让  PieChart  和  BarChart  分别去实现这个接口。
// 抽象层
public interface Chart {
void display();
}

// 具体实现
public class PieChart implements Chart {
public void display() { System.out.println("显示饼状图"); }
}

public class BarChart implements Chart {
public void display() { System.out.println("显示柱状图"); }
}
这样一来, ChartDisplay  类就不再依赖具体的图表类,而是依赖抽象的  Chart  接口。当需要新增折线图时,我们只需要新建一个  LineChart  类实现接口即可,完全不需要修改原有的  ChartDisplay  代码。

  1. 拒绝臃肿:登录功能的“大瘦身”

第二个案例展示了一个名为  Login  的类,它简直是一个“万能工具箱”。请看它的成员方法:

init() :初始化

display() :界面显示

validate() :数据校验

getConnection() :数据库连接

findUser(...) :业务查询

main(...) :程序入口

这个类严重违反了单一职责原则(Single Responsibility Principle, SRP)。
一个类应该只有一个引起它变化的原因。但在上面的  Login  类中,如果 UI 变了要改它,数据库密码变了要改它,验证逻辑变了也要改它。这就导致代码耦合度极高,牵一发而动全身,维护起来简直是噩梦。

重构方案:职责分离
我们需要将这个庞大的类进行拆分:

UI 层:将  display()  和  init()  剥离出来,放入  LoginView  类,专门负责界面交互。

数据访问层(DAO):将  getConnection()  和  findUser()  剥离出来,放入  UserDAO  类,专门负责和数据库打交道。

业务逻辑层:保留  validate()  在  LoginService  或  LoginController  中,作为协调者,调用 View 获取数据,调用 DAO 验证数据。

结语

无论是 CRM 图表系统的重构,还是登录类的拆分,其核心思想都是解耦。
开闭原则告诉我们要用“抽象”来隔离变化,让系统易于扩展。
单一职责原则告诉我们要用“分工”来降低复杂度,让系统易于维护。

posted @ 2026-06-09 22:56  定缘  阅读(9)  评论(0)    收藏  举报