6大设计原则详解(一)

1. 单一职责原则(SRP)

(1)概念

单一职责原则的定义是:应该有且只有一个原因引起类的改变,即一个类只负责一个职责。

比如让类C负责两个不同的职责:职责P1,P2。当由于职责P1需求发生改变而需要修改类C时,有可能会导致原本运行正常的职责P2功能发生故障。

(2)举例

关于用户管理的一个类按如下类图来设计:

很显然,用户的属性和行为没有分开,按照单一职责原则,应该将其重新拆封成两个接口:用户属性接口IUserBO,用户行为接口IUserBiz。

分清职责之后的代码如下:

......
IUserInfo userInfo = new UserInfo();
// 操作用户的属性
IUserBo userBo = (IUserBo)userInfo;
userBo.setPassword("123");
// 操作用户的行为
IUserBiz userBiz = (IUserBiz)userInfo;
userBiz.delete(userBo);
......

(3)总结

单一职责原则适用于接口、类、方法,一个方法尽可能地完成一件事情。比如一个修改密码的方法,就不要把它放在修改用户信息这个大的方法中去,否则方法的职责就不清晰了。但是过分细分类的职责又会人为的增加系统的复杂性,比如本来一个类可以实现的行为硬拆分为两个类,然后再使用聚合或者组合的方式耦合在一起,就人为的制造了麻烦。由于单一的职责这个“职责”没有一个量化的标准,所以最难划分的还是职责,这个还是要根据实际情况和个人经验来定。

2. 里氏替换原则(LSP)

(1)概念

里氏替换原则针对的对象是具有继承关系的子类和父类。

里氏替换原则的定义是:只要父类出现的地方子类就可以出现,而且将其替换为子类也不会产生任何出错或者异常。

子类必须完全实现父类的方法(方法不能为空)。即父类的方法必须是子类全部需要的,如果不是全部需要的,就违背了LSP原则。

在类中调用其他类时必须使用父类或者接口,如果不使用父类或者接口,则类的设计违背了LSP原则。

(2)举例

某公司有普通用户和vip用户,他们发邮件的过程如下:

分析发现普通用户和vip用户发邮件的过程是相同的,即两个send()方法重复。将来还可能增加用户新类型,为了让系统具有更好的扩展性,使用里氏替换原则进行重构:

(3)总结

里氏替换原则包含以下4层含义:

子类必须完全实现父类的方法(方法体不为空);

子类可以有自己特有的方法;

重写父类的方法时输入参数可以被放大(子类中重写父类方法的前置条件必须与父类中被重写方法的前置条件相同或者更宽松);

重写父类的方法时输出结果可以被缩小(子类中重写父类方法的返回值必须小于等于父类中被重写方法的返回值)。

当然如果在编程过程中违反了LSP原则在运行时也不会出现什么问题,但是会遗留下很多潜在的问题会给以后的变更、维护工作造成很大的困难。

3. 依赖倒置原则(DIP)

(1)概念

依赖倒置原则的定义是:实现类之间不发生直接的依赖关系,其依赖关系是通过接口或者抽象类产生的。即面向接口编程。

实现类依赖接口或者抽象类,而接口或者抽象类不依赖于实现类。

(2)举例

司机开奔驰车的类图如下:

实现代码如下:

// 司机的实现类
public class Driver {
    public void drive(Benz benz) {
        benz.run();
    }
}
// 奔驰车的实现类
public class Benz {
    public void run() {
        System.out.println("奔驰车出发...");
    }
}
// 场景调用类
public class Scene {
    public static void main(String[] args) {
        Driver driver = new Driver();
        Benz benz = new Benz();
        driver.drive(benz);
    }
}

看起来好像这样设计是没有任何问题的,但我们常说“危难时刻见真情“,在技术上即“变更才显真功夫”。现在司机不仅要开奔驰,要开宝马车。但司机driver只有开奔驰的方法,而没有开动宝马车的方法啊,这就不合理了。这里只是增加了一个车类就要修改司机类,这是不稳定的、易变的。引用依赖倒置原则,采用面向接口编程的思想设计类图如下:

实现代码如下:

// 司机接口类
public interface IDriver {
    public void drive(ICar car);
}
// 汽车接口类
public interface ICar {
    public void run();
}
// 司机的实现类
public class Driver implements IDriver {
    @Override
    public void drive(ICar car) {
        car.run();
    }
}
// 奔驰车的实现类
public class Benz implements ICar {
    @Override
    public void run() {
        System.out.println("奔驰车出发...");
    }
}
// 宝马车的实现类
public class BMW implements ICar {
    @Override
    public void run() {
        System.out.println("宝马车出发...");
    }
}

(3)总结

依赖倒置原则的本质就是通过抽象(接口或抽象类)使各个类或模块的实现彼此独立,不相互影响,实现模块间的松耦合。

每个类应该尽量都有接口或者抽象类,或者两者都有。

变量的表面类型尽量是接口或者抽象类。

依赖倒置原则使类之间不存在依赖关系,可以进行独立的并行开发,而且两个类的单元测试也可以独立地运行。

6大设计原则详解(二):http://www.cnblogs.com/LangZXG/p/6242927.html

6大设计原则,与常见设计模式(概述):http://www.cnblogs.com/LangZXG/p/6204142.html

类图基础知识:http://www.cnblogs.com/LangZXG/p/6208716.html

注:转载请注明出处   http://www.cnblogs.com/LangZXG/p/6242925.html

时间: 2024-10-29 19:08:05

6大设计原则详解(一)的相关文章

设计模式原则详解

我们在应用程序开发中,一般要求尽量两做到可维护性和可复用性.       应用程序的复用可以提高应用程序的开发效率和质量,节约开发成本,恰当的复用还可以改善系统的可维护性.而在面向对象的设计里面,可维护性复用都是以面向对象设计原则为基础的,这些设计原则首先都是复用的原则,遵循这些设计原则可以有效地提高系统的复用性,同时提高系统的可维护性. 面向对象设计原则和设计模式也是对系统进行合理重构的指导方针. 常用的面向对象设计原则包括7个,这些原则并不是孤立存在的,它们相互依赖,相互补充. 1.单一职责

【设计模式】设计模式原则详解

我们在应用程序开发中,一般要求尽量两做到可维护性和可复用性.       应用程序的复用可以提高应用程序的开发效率和质量,节约开发成本,恰当的复用还可以改善系统的可维护性.而在面向对象的设计里面,可维护性复用都是以面向对象设计原则为基础的,这些设计原则首先都是复用的原则,遵循这些设计原则可以有效地提高系统的复用性,同时提高系统的可维护性. 面向对象设计原则和设计模式也是对系统进行合理重构的指导方针. 常用的面向对象设计原则包括7个,这些原则并不是孤立存在的,它们相互依赖,相互补充. 1.单一职责

Java内存模型相关原则详解

在<Java内存模型(JMM)详解>一文中我们已经讲到了Java内存模型的基本结构以及相关操作和规则.而Java内存模型又是围绕着在并发过程中如何处理原子性.可见性以及有序性这三个特征来构建的.本篇文章就带大家了解一下相关概念.原则等内容. 原子性 原子性即一个操作或一系列是不可中断的.即使是在多个线程的情况下,操作一旦开始,就不会被其他线程干扰. 比如,对于一个静态变量int x两条线程同时对其赋值,线程A赋值为1,而线程B赋值为2,不管线程如何运行,最终x的值要么是1,要么是2,线程A和线

面向对象编程6大设计原则:单一职责原则

单一职责原则(Single  Responsibility Principle)简称SRP原则. 定义 应该有且仅有一个原因引起类的变更. 优点 可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多: 提高类的可读性,提高系统的可维护性: 变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响. 说明 单一职责原则不只是面向对象编程思想所特有的,只要是模块化的程序设计,都适用单一职责原则: 单一职责原则要根据项目的实际情

设计模式之6大设计原则

设计模式之6大设计原则 原则一:单一职责原则(Single Responsibility Principle SRP) 定义:There should never be more than one reason for a class to change.(应该有且仅有一个原因引起类的变更) 好处: 1.类的复杂性降低,实现什么职都有清晰明确的定义: 2.可读性高,负责性降低,当然可读性就提高了: 3.可维护性提高,可读性提高,自然就更容易维护了: 4.变更引起的风险降低,变更是必不可少的,如果

6大设计原则之依赖倒置原则

依赖倒置原则: 包含三层含义: 高层模块不应该依赖低层模块,二者应该依赖抽象 抽象不应该依赖细节 细节应该依赖抽象 再精简些就是:其核心是面向接口编程 抽象:即抽象类和接口,抽象是对实现的约束,对依赖而言也是一种契约 细节:即具体的实现类,实现接口或继承抽象类所产生的类 依赖倒置就是通过抽象使各个类或模块间实现彼此独立,互不影响,实现模块间的松耦合. 依赖的三种实现方式: 构造函数注入 Setter依赖注入 接口注入 6大设计原则之依赖倒置原则

设计模式——6大设计原则

1.单一职责原则 单一职责原则的英文名称是Single Responsibility Principle,简称是SRP. 单一职责的定义是:有且仅有一个原因引起类的变更. 单一职责原则要求一个接口或者一个类只有一个原因引起变化,也就是说一个接口或类只有一个职责,它就负责一件事情. 建议是:接口一定要做到单一职责,类的世界尽量做到只有一个原因引起变化.2.里氏替换原则 里氏替换原则的英文名称是Liskov Substitution Principle,简称是LSP. 里氏替换原则的定义:所有引用基

分享《深度学习与计算机视觉算法原理框架应用》PDF《大数据架构详解从数据获取到深度学习》PDF +数据集

下载:https://pan.baidu.com/s/12-s95JrHek82tLRk3UQO_w 更多分享资料:https://www.cnblogs.com/javapythonstudy/ <深度学习与计算机视觉 算法原理.框架应用>PDF,带书签,347页.<大数据架构详解:从数据获取到深度学习>PDF,带书签,373页.配套源代码. <深度学习与计算机视觉 算法原理.框架应用>全书共13章,分为2篇,第1篇基础知识,第2篇实例精讲.用通俗易懂的文字表达公式背

分享《深度学习与计算机视觉算法原理框架应用》《大数据架构详解从数据获取到深度学习》PDF数据集

下载:https://pan.baidu.com/s/12-s95JrHek82tLRk3UQO_w 更多资料分享:http://blog.51cto.com/3215120 <深度学习与计算机视觉 算法原理.框架应用>PDF,带书签,347页.<大数据架构详解:从数据获取到深度学习>PDF,带书签,373页.配套源代码. <深度学习与计算机视觉 算法原理.框架应用>全书共13章,分为2篇,第1篇基础知识,第2篇实例精讲.用通俗易懂的文字表达公式背后的原理,实例部分提供