设计模式六大原则(一)----单一职责原则 (2)

上面做家务不是定义成一个接口, 而是将扫地和做家务分开了. 张三扫地, 那么张三就实现扫地的接口. 李四购物, 李四就实现购物的接口. 后面李四要增加一个功能做饭. 那么就新增一个做饭接口, 这次只需要李四实现做饭接口就可以了.

public interface Cooking extends Hoursework{ void cooking(); } public class Lisi implements Shopping, Cooking{ @Override public void shopping() { // 李四购物 } @Override public void cooking() { // 李四做饭 } }

如上, 我们看到张三没有实现多余的接口, 李四也没有. 而且当新增功能的时候, 只影响了李四, 并没有影响张三.
这就是符合单一职责原则. 一个类只做一件事. 并且他的修改不会带来其他的变化.

3.3 【类层面】单一职责原则的应用

从类的层面来讲, 没有办法完全按照单一职责原来来拆分. 换种说法, 类的职责可大可小, 不想接口那样可以很明确的按照单一职责原则拆分. 只要符合逻辑有道理即可.

比如, 我们在网站首页可以注册, 登录, 微信登录.注册登录等操作. 我们通常的做法是:

public interface UserOperate { void login(UserInfo userInfo); void register(UserInfo userInfo); void logout(UserInfo userInfo); } public class UserOperateImpl implements UserOperate{ @Override public void login(UserInfo userInfo) { // 用户登录 } @Override public void register(UserInfo userInfo) { // 用户注册 } @Override public void logout(UserInfo userInfo) { // 用户登出 } }

那如果按照单一职责原则拆分, 也可以拆分为下面的形式

public interface Register { void register(); } public interface Login { void login(); } public interface Logout { void logout(); } public class RegisterImpl implements Register{ @Override public void register() { } } public class LoginImpl implements Login{ @Override public void login() { // 用户登录 } } public class LogoutImpl implements Logout{ @Override public void logout() { } }

像上面这样写可不可以呢? 其实也可以, 就是类很多. 如果登录、注册、注销操作代码很多, 那么可以这么写.

四、如何遵守单一职责原则 4.1 合理的职责分解

相同的职责放到一起,不同的职责分解到不同的接口和实现中去,这个是最容易也是最难运用的原则,关键还是要从业务出发,从需求出发,识别出同一种类型的职责。

例子:人的行为分析,包括了生活和工作等行为的分析,生活行为包括吃、跑、睡等行为,工作行为包括上下班,开会等行为,如下图所示:

设计模式六大原则(一)----单一职责原则

人类的行为分成了两个接口:生活行为接口、工作行为接口,以及两个实现类。如果都用一个实现类来承担这两个接口的职责,就会导致代码臃肿,不易维护,如果以后再加上其他行为,例如学习行为接口,将会产生变更风险(这里还用到了组合模式)。

4.2 来看看简单的代码实现 第一步: 定义一个行为接口 /** * 人的行为 * 人的行为包括两种: 生活行为, 工作行为 */ public interface IBehavior { }

这里面定义了一个空的接口, 行为接口. 具体这个行为接口下面有哪些接口呢?有生活和工作两方面的行为.

第二步: 定义生活和工作接口, 并且他们都是行为接口的子类

生活行为接口:

public interface LivingBehavior extends IBehavior{ /** 吃饭 */ void eat(); /** 跑步 */ void running(); /** 睡觉 */ void sleeping(); }

工作行为接口:

public interface WorkingBehavior extends IBehavior{ /** 上班 */ void goToWork(); /** 下班 */ void goOffWork(); /** 开会 */ void meeting(); } 第三步: 定义工作行为接口和生活行为接口的实现类

生活行为接口实现类:

public class LivingBehaviorImpl implements LivingBehavior{ @Override public void eat() { System.out.println("吃饭"); } @Override public void running() { System.out.println("跑步"); } @Override public void sleeping() { System.out.println("睡觉"); } }

工作行为接口实现类:

public class WorkingBehaviorImpl implements WorkingBehavior{ @Override public void goToWork() { System.out.println("上班"); } @Override public void goOffWork() { System.out.println("下班"); } @Override public void meeting() { System.out.println("开会"); } } 第四步: 行为组合调用.

行为接口定义好了. 接下来会定义一个行为集合. 不同的用户拥有的行为是不一样 , 有的用户只用生活行为, 有的用户既有生活行为又有工作行为.ewgni

我们并不知道具体用户到底会有哪些行为, 所以,通常使用一个集合来接收用户的行为. 用户有哪些行为, 就往里面添加哪些行为.

1. 行为组合接口BehaviorComposer public interface BehaviorComposer { void add(IBehavior behavior); } 2. 行为组合接口实现类IBehaviorComposerImpl public class IBehaviorComposerImpl implements BehaviorComposer { private List<IBehavior> behaviors = new ArrayList<>(); @Override public void add(IBehavior behavior) { System.out.println("添加行为"); behaviors.add(behavior); } public void doSomeThing() { behaviors.forEach(b->{ if(b instanceof LivingBehavior) { LivingBehavior li = (LivingBehavior)b; // 处理生活行为 } else if(b instanceof WorkingBehavior) { WorkingBehavior wb = (WorkingBehavior) b; // 处理工作行为 } }); } } 第五步: 客户端调用

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwyfjg.html