Bootstrap

设计模式-单一职责及接口隔离原则

一:单一职责原则

简单理解就是,一个类只负责一项职责

若一个DAO类即可以操作user表,又可以操作order表,则不符合单一职责原则

应该分成两个DAO类(只有类中方法数量比较少,可以在方法级别上保持单一职责原则)

二:接口隔离原则

含义:一个类对另一个类的依赖应该建立在最小接口上,使用多个专门的接口比使用单一的总接口要好。
这么说可能不好理解,看完下边这个栗子,在看刚刚的定义,你会更容易理解。
举例:
有这样一个需求

系统中有三种角色,三个角色对订单的操作如下:
用户,只能有查询订单的方法
商家,只能有查询、添加订单的方法
管理员,有添加、删除、修改、查询订单的方法

实现方式一:
  1. 定义一个订单接口IOrder,其中包含增删改查四个方法,待实现类实现,代码如下:
//订单接口
interface IOrder{
	public void addOrder();
	public void deleteOrder();
	public void updateOrder();
	public void getOrder();
}
  1. 实现类Order继承接口IOrder,实现其内的方法,代码如下:
class Order implements IOrder{
	//使用输出字符串 模拟 具体操作
	@Override
	public void addOrder() {
		System.out.println("添加订单");
	}
	@Override
	public void deleteOrder() {
		System.out.println("删除订单");
	}
	@Override
	public void updateOrder() {
		System.out.println("修改订单");
	}
	@Override
	public void getOrder() {
		System.out.println("查询订单");
	}
}
  1. 测试
public class IsolateTest {
	//模拟用户使用系统
	//参数传入类型为接口IOrder,是为了满足“依赖倒转原则”,其实就是为了方便扩展,后续博客会讲解
	public static void UserUseSystem(IOrder order) {
		System.out.println("用户使用系统开始");
		order.getOrder();
		System.out.println("用户使用系统结束\n");
	}
	//模拟商家使用系统
	public static void ShopUseSystem(IOrder order) {
		System.out.println("商家使用系统开始");
		order.getOrder();
		order.addOrder();
		System.out.println("商家使用系统结束\n");
	}
	//模拟管理员使用系统
	public static void AdminUseSystem(IOrder order) {
		System.out.println("管理员使用系统开始");
		order.getOrder();
		order.addOrder();
		order.deleteOrder();
		order.updateOrder();
		System.out.println("管理员使用系统结束\n");
	}
	public static void main(String[] args) {
		//在不同角色使用系统时
		IOrder order=new Order();
		UserUseSystem(order);
		ShopUseSystem(order);
		AdminUseSystem(order);
	}
}
//输出结果可想而知,此处省略

这种方式虽然满足基本的需求,但是用户、商家、管理员都有了对订单增删改查的方法,但其实添加、删除、修改操作方法对用户来说是没有用的(或者说不安全的

接下来,根据接口隔离的原则,对代码进行改进。

实现方式二:

再看一眼接口隔离原则:一个类对另一个类的依赖应该建立在最小接口上,使用多个专门的接口比使用单一的总接口要好。

因此,我们可以把IOrder这个总接口,拆成针对不同角色的专门接口

  1. 接口拆分,代码如下
//接口隔离实现方法,将订单接口进行拆分,拆分分别面向用户、商家、管理员的接口
interface IOrderForUser{
	//只有查询操作
	public void getOrder();
}

interface IOrderForShop{
	//只有添加、查询操作
	public void addOrder();
	public void getOrder();
}

interface IOrderForAdmin{
	//增删改查
	public void addOrder();
	public void deleteOrder();
	public void updateOrder();
	public void getOrder();
}
  1. 实现类Order继承接口IOrderForUser、IOrderForShop、IOrderForAdmin,实现其内的方法,代码如下:
class Order implements IOrderForUser,IOrderForShop,IOrderForAdmin{
	@Override
	public void addOrder() {
		System.out.println("添加订单");
	}
	@Override
	public void deleteOrder() {
		System.out.println("删除订单");
	}
	@Override
	public void updateOrder() {
		System.out.println("修改订单");
	}
	@Override
	public void getOrder() {
		System.out.println("查询订单");
	}
}
  1. 测试
public class IsolateTest {
	//模拟用户使用系统
	public static void UserUseSystem(IOrderForUser order) {
		System.out.println("用户使用系统开始");
		order.getOrder();
		System.out.println("用户使用系统结束\n");
	}
	//模拟商家使用系统
	public static void ShopUseSystem(IOrderForShop order) {
		System.out.println("商家使用系统开始");
		order.getOrder();
		order.addOrder();
		System.out.println("商家使用系统结束\n");
	}
	//模拟管理员使用系统
	public static void AdminUseSystem(IOrderForAdmin order) {
		System.out.println("管理员使用系统开始");
		order.getOrder();
		order.addOrder();
		order.deleteOrder();
		order.updateOrder();
		System.out.println("管理员使用系统结束\n");
	}
	public static void main(String[] args) {
		//在不同角色使用系统时
		IOrderForUser iOrderForUser=new Order();
		IOrderForShop iOrderForShop=new Order();
		IOrderForAdmin iOrderForAdmin=new Order();
		UserUseSystem(iOrderForUser);
		ShopUseSystem(iOrderForShop);
		AdminUseSystem(iOrderForAdmin);
	}
}
//输出结果同实现方式一

实现方式二就解决了实现方式一中 用户、商家、管理员都有了对订单增删改查的操作的问题。

后记:

在书写博客过程中,想过另外一种讲解方法,大体思路是这样的:

实现方式一:
  1. 定义一个订单接口IOrder,其内包含 增删改查 四个待实现方法。
  2. 用户订单实现类UserOrder、商家订单实现类ShopOrder、管理员订单实现类AdminOrder分别实现接口IOrder。(因为考虑到不同角色对订单的同一个操作,可能不同)
  3. 然后说明一下,用户订单实现类UserOrder其实不需要实现订单接口IOrder中的添加、删除、修改方法,以此说明这种方法不好。
    引出
实现方式二:
  1. 定义三个接口
    接口IGetOrder:其内有只有查询订单的方法。
    接口IAddOrder:其内有只有添加订单的方法。
    接口IUpdateAndDeleteOrder:其内有修改、删除订单的方法。
  2. 然后
    用户订单实现类UserOrder实现接口IGetOrder。
    商家订单实现类ShopOrder实现接口IGetOrder和IAddOrder。
    管理员订单实现类AdminOrder实现接口IGetOrder和IAddOrder和IUpdateAndDeleteOrder。
    这样就解决的实现方式一中的问题,满足接口隔离原则。

参考链接:接口隔离原则

;