类设计原则
来源:互联网 发布:如何评价魔兽世界 知乎 编辑:程序博客网 时间:2024/06/05 02:18
Java 面向对象的类的设计原则
1. 依赖倒置原则(Dependency Inversion Principle)
模块:指能够单独命名并独立 完成一定功能的程序语句集合。
依赖:在程序设计中,如果模块a调用了模块b,我们称模块a依赖模块b。
抽象:即抽象类或接口,是不能够实例化的。
细节:即具体的实现类,实现接口或者继承抽象类所产生的类,可以通过关键字new直接被实例化。
原则: 1. 高层模块不应该依赖低层模块,二者都应该依赖抽象。
2. 抽象不应该依赖细节,细节应该依赖抽象。
依赖于抽象:建议不应该依赖于具体类,也就是说,程序中所有的依赖关系都应该终止于抽象类或者接口。
根据这个规则可知:
1. 任何变量都不应该持有一个指向具体类的指针或者引用。
2. 任何类都不应该从具体类中派生。
3.任何方法都不应该覆写它的任何基类中的已经实现的方法。
当然如果一个类不太会改变,并且也不会创建其他类型的派生类,那么依赖于它并不会造成损害。比如Java中的String具体类。
Robert C .Martin在原文中给出了Bad Design 的定义:
1. 系统很难改变,因为每个改变都会影响到其他很多部分。
2. 当你对某地方做一修改,系统的看似无关的其他部分都不工作了。
3. 系统很难被另外一个应用重用,因为你很难将要重用的部分从系统中分离开来。
依赖倒置原则提出的缘由:类A直接依赖类B,加入要将类A改成依赖类C,则必须通过改类A的代码来达成。这种场景下,类A一般是高层的模块,负责复杂的业务逻辑;类B
和类C是低层模块,负责基本的原子操作;修改了A则会带来不必要的风险。
依赖倒置原则解决方案:类A的依赖改成接口I,类B和类C来实现接口I,这样就行成了如图的模式:
这样,类A 通过接口I间接与类B 或者类C发生关系,则会大大降低修改类A的几率。
依赖倒置原则基于这样一个事实:相对于细节的多变性,抽象的东西要稳定的多,以抽象为基础搭建起来的框架比以细节建起来的狂建要稳定的多。
实际编程中需要注意:
1.低层模块尽量要抽象类或者接口。
2. 变量的声明类型尽量是抽象类或接口。
3. 使用继承时要遵循里氏替换原则
2. 里氏替换原则(Liskov Substitution Principle)
1. 不应该在代码出现if/else之类类型进行判断的条件
2. 类应可以代替父类能够出现的任何地方,或者说如果我们把代码中使用基类的地方用它的子类所代替,代码还能正常工作。
问题由来:类A封装了功能P1,子类B继承了类A,为了满足需求,需要扩展子类B的功能,然后重写了类A的封装方法实现新功能,这样就导致了原有功能在应用的时候发生
故障。
解决方案:在使用继承的时候,子类除了添加新功能外,尽量不要重写父类的方法,也尽量不要重载父类的方法。
Ps:重写的方法名和参数数目相同,参数类型兼容,子类方法覆盖父类的方法。
重载最常见的例子就是构造函数。
继承包含这样一层含义:父类中凡是已经实现好的方法,实际上是在舌钉一系列的规范和契约,虽然它不强制要求所有的子类必须遵从这些契约,但是如果子类对这些非抽
象方法任意修改,就会对整个继承体系造成破坏。
比如如下例子:
public class A { public int func1(int a, int b) { return a-b; }}public class Client{ public static void main(String[] args) { A a = new A(); System.out.println("100-50="+a.func1(100,50)); System.out.println("100-80="+a.func1(100,80)); }}
100-50=50100-80=20
如果对类A进行继承重写方法:
public class A { public int func1(int a, int b) { return a-b; }}class B extends A{ public int func1(int a,int b) { return a+b; } public int func2(int a, int b) { return func1(a,b)+100; }}public class Client{ public static void main(String[] args) { B b = new B(); System.out.println("100-50=" + b.func1(100, 50)); System.out.println("100-80=" + b.func1(100, 80)); System.out.println("100+20+100="+b.func2(100,20)); }}
结果:
100-50=150100-80=180100+20+100=220
重写了方法,子类的实现就会和父类有差别,因为我们对父类的方法时熟知的,这样就会造成我们对结果的迷茫。
里氏替换原则通俗来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能。
里氏替换原则是使代码符合开闭原则的一个重要保证。
3. 开闭原则(Open Closed Principle)
- 对修改关闭。某模块被其他模块调用,如果该模块的源代码不允许修改,则该 模块修改关闭的。软件系统的功能上的稳定性,持续性要求是修改关闭的。
2. 对扩展开放。某模块的功能是可扩展的,则该模块是扩展开放的。软件系统的功能上的可扩展性要求模块是扩展开放的。
开闭原则大致说:用抽象构件框架,用实现扩展细节(不够准确)。
问题由来:在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不对整个功能进行重
构,并且需要原有代码经过重新测试。
解决方法:当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有代码来实现变化。
其实开闭原则是一种整体总结性的原则,它好像说了所有的东西,又好像没说什么实际的,不过在真正操作的时候很难保证开闭原则。有时我们做项目的时候会遇到
各种情况,很多时候就会违反原则了
4. 单一职责原则(Single Responsibility Principle)
原则:只能让一个类有且仅有一个职责。
原因:如果一个类具有一个以上的职责,那么就会有多个不同的原因引起该类变化,而这种变化将影响到该类不同职责的使用者。
1. 一方面,如果一个职责使用了外部类库,则使用另一个职责的用户却也不得不包含这个未使用的 外部类库。
2. 另一方面,某个用户由于某种原因修改了其中一个职责,另外一个职责的用户也将受到影响,它将不得不重新编译和配置。这违反了设计的开闭原则。
如何划分职责:所谓一个类的一个职责是指引该类变化的一个原因。如果你能想到一个类存在多个使其改变的原因,那么这个类就存在多个职责。
例如:在设计接口Modem的时候,有拨号,挂断,发送数据和接收数据的功能,其中我们的连接管理(拨号和挂断)和数据传输(发送数据和接收数据)之间并没有相通的地方,它们会因为不同理由而改变。这样 就违反了SRP原则。
5. 接口分离原则(Interface Segregation Principle)
原则:
1. 接口的设计原则:接口的设计应该遵循最小接口原则,不要把用户不使用的方法塞在同一个接口里。
2. 接口依赖(继承)原则:如果一个接口a依赖另一个接口b,则接口a相当于集成了接口b的方法,那么继承了接口b后的所有接口a也应该遵循上述原则。
提出原因:如果用户被迫依赖他们不使用的接口,当接口发生变化时,他们也不得不跟着改变。换句话说,一个用户依赖了未使用但被其他用户使用的接口,当其他用户修改了该接口时,依赖该接口的所有用户将受到影响。这显然违反了开闭原则。
比如:
有一个Door,有lock和unlock功能 ,另外,可以在Door上安装一个Alarm而使其具有报警功能。用户可以选择一般的Door,也可以选择具有报警功能的Door。
设计方案:
在Alarm接口定义alarm方法,在Door接口定义lock和unlock方法。接口之间没有继承关系。CommonDoor实现Door接口,AlarmDoor同时实现Door 和Alarm接口。
如果我们直接把Alarm 功能集成在了Door上,那么我们的CommonDoor就用不到alarm功能。
- 面向对象设计原则-类设计原则
- 类设计原则
- 类设计原则
- 类设计指导原则
- C++类设计原则
- 类的设计原则
- 类设计原则
- 类的设计原则
- 类的设计原则
- 类的设计原则
- 类的设计原则
- 类设计原则
- 类的设计原则
- C++类设计原则
- 类的设计原则
- 面向对象的设计原则-类设计原则
- 面向对象的设计原则-类设计原则(转载)
- 面向对象的设计原则-类设计原则
- 运算符.强制类型转换等
- 拷贝构造函数
- mssql中的数据转存到Mysql中
- HDU 5733 tetrahedron (2016 Multi-University Training Contest 1 计算几何)
- mysql的索引
- 类设计原则
- kdtree c++版本
- 杭电5478Can you find it
- mac在安装genymotion下遇到的种种问题
- 关于如何求无向无环图中所有两点之间的长度和
- K-means算法上
- 《机器学习中的数学》第一课笔记1.1
- Linux ldconfig 查看动态库连接
- 《ShareX 》截图神器