TIP

设计模式的原则有的书上是六大原则,有的是七大原则,本次以七大原则介绍。设计模式一词是一个建筑学家提出的,可见不管做什么都是要精打细算的。

# 判断软件设计质量的标准

高内聚,低耦合,执行这些原则也是为了使代码更加靠近这一标准。

# 单一职责原则(Single-Responsibility Principle)

  • 定义:一个类只负责一个功能领域中相应的职责,或者可以定义为:就一个类而言,应该只有一个引起它变化的原因。

  • 目的:为了实现高内聚。一个类承担的职责越多,被复用的可能性就越小,一个类承担的职责过多,就相当于把这些职责耦合在一起,当以职责发生变化时(即,功能),可能会影响到其他的职责工作,所以要将这些职责进行分离,将不同的职责封装在不同的类中,即将不同的变化原因封装在不同的类中。

  • 优点:

    1. 可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定比负责多项职责简单。
    2. 可读性高
    3. 可维护性高,修改代码的时候风险也小。如果接口的单一职责好,一个接口的修改只对应相应的实现类有影响,对其他接口无影响,提高了系统的扩展性和可维护性。

# SRP例子

问题背景,现在有一个客户管理系统,需要一个绘制客户表的工具。

public class Main {//代码段1
	public static void main(String[] args) {
		System.out.println("This Main SRP");
		new CustomerChart().displayChart();
	}
}
import java.util.ArrayList;
import java.util.List;
public class CustomerChart {//代码段2
	protected List<Customer> findCustomers() {
		//查找数据库
		List<Customer> ret = new ArrayList<Customer>();
		ret.add(new Customer("www",20));
		ret.add(new Customer("mmm",26));
		return ret;
	}
	public void displayChart() {
		for (Customer customer : findCustomers()) {
			System.out.println("customer:" + customer.name);
		}
	}
}
public class Customer {//代码段3
	public String name;
	public int age;
	public Customer(String name,int age) {
		this.name = name;
		this.age = age;
	}
}
  • 类图

CustomerChart# findCustomers(): List<Customer>+ displayChart(): void MainCustomer+ name: String
+ age: int
+ age: int
+ Customer(name:String,age:int)
Use
Use
Use
Use

假如之前使用的是mysql数据库,现在要换成oracle怎么办?

之前是把绘图和查询数据库放在了一起,当数据库发生改变时,需要修改数据库部分,但是绘图部分并没有改变,显然他们发生变化的原因并不一致,所以需要将他们两个隔离开来。

  • 代码段3数据库部分与绘图部分拆成两个类,形成代码段4代码段5
public class CustomerChart {//代码段4
	public CustomerDao dao = null;
	public CustomerChart(CustomerDao dao) {
		this.dao = dao;
	}
	public void displayChart() {
		for (Customer customer : dao.findCustomers()) {
			System.out.println("customer:" + customer.name);
		}
	}
}
import java.util.ArrayList;
import java.util.List;
public class CustomerDao {//代码段5
	protected List<Customer> findCustomers() {
		//查找数据库
		List<Customer> ret = new ArrayList<Customer>();
		ret.add(new Customer("www",20));
		ret.add(new Customer("mmm",26));
		return ret;
	}
}
  • 类图

CustomerChart
+ customerDao: CustomerDao
+ customerDao: CustomerDao
+ displayChart(): void MainCustomer+ name: String
+ age: int
+ age: int
+ Customer(name:String,age:int)
Use
Use
CustomerDao# findCustomers(): List<Customer>
Use
Use
为什么是聚合而不是依赖呢?
为什么是聚合而不是依赖呢?