- 单一职责原则——Single Responsiblity Principle
- SRP的定义:就一个类而言,应该仅有一个引起它变化的原因(也就是说一个接口或类只有一个职责,只负责一件事情)。简单来说,一个类应该是一组相关性很高的函数、数据的封装。
-
这样就没有遵循单一职责原则,因为该接口同时包含了用户的属性和用户的行为。
-
这样也没有遵循单一职责原则,dial()和hangup()两个方法实现的是协议管理,分别负责拨号接通和挂机;chat()实现的是数据的传送。
-
将其修改成如此结构就满足了单一职责原则。你会觉得这个Phone有两个原因引起变化了呀,是的,但是别忘记了我们是面向接口编程,我们对外公布的是接口而不是实现类。
-
Phone phone=new Phone(); -
//面向接口编程,对外公布接口而不是实现类 -
IConnectionManager icm=(IConnectionManager)phone; -
IDataTransfer idt=(IDataTransfer)phone;
-
- 单一原则适用于接口、类,同时也适用于方法。一个方法尽可能作一件事情。
- 对于类来说做到单一职责原则比较困难,所以接口一定要做到单一职责,类的设计尽量做到只有一个原因引起变化。
- 里氏替换原则——Liskov Substitution Principle
- 定义:所有引用基类的地方必须能透明地使用其子类的对象。通俗点讲,只要父类能出现的地方子类就可以出现,而且替换为子类也不会产生任何错误或异常,使用者可能根本就不需要知道是父类还是子类。但是,反过来就不行了,有子类出现的地方,父类未必就能适应。
- 子类必须完全实现父类的方法。如果子类不能完整地实现父类的方法,或者父类的某些方法在子类中已经发 生“畸变”,则建议断开父子继承关系,采用依赖、聚集、组合等关系代替继承。
- 子类可以有自己的个性。从里氏替换原则来看,就是有子类出现的地方父类未必就可以出现。
- 覆盖或实现父类的方法时输入参数可以被放大。
结果是:父类被执行。父类方法的输入参数是HashMap类型,子类的输入参数是Map类型,也就是说子类的输入参数类型的范围扩大了,子类代替父类传递到调用者中,子类的方法永远都不会被执行。这是正确的,如果你想让子类的方法运行,就 必须覆写父类的方法。
- 覆写或实现父类的方法时输出结果可以被缩小。父类的一个方法的返回值是一个类型T,子类的相同方法(重载或覆 写)的返回值为S,那么里氏替换原则就要求S必须小于等于T,也就是说,要么S和T是同一 个类型,要么S是T的子类。
- 依赖倒置原则——Dependence Inversion Principle
- 依赖倒置原则指代了一种特定的解耦形式,使得高层的模块不依赖与低层次的模块的实现细节的目的。
- 关键点:高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节; 细节应该依赖抽象。
-
。两个类之间有依赖关系,只要制定出两者之间的接口(或抽象类)就可以独立开发了,而且项目之间的单元测试也可以独立地运行。
- 依赖的三种写法:构造函数传递依赖对象;setter方法传递依赖对象;接口声明依赖对象。
- 遵循的规则:
- 接口隔离原则——InterfaceSegregation Principles
- 定义:客户端不应该依赖它不需要的接口;类间的依赖关系应该建立在最小的接口上。说第一种“客户端不应该依赖它不需要的接口”,那依赖什么?依赖它需要的接口,客户端需要什么接口就提供什么接口,把不需要的接口剔除掉,那就需要对接口进行细化,保证其纯洁性;再看第二种定义:“类间的依赖关系应该建立在最小的接口上”,它要求是最小的接口,也是要求接口细化,接口纯洁,与第一个定义如出一辙,只是一个事物的两种不同描述。
-
-
public interface IGoodBodyGirl { -
//要有姣好的面孔 -
public void goodLooking(); -
//要有好身材 -
public void niceFigure(); -
} -
public interface IGreatTemperamentGirl { -
//要有气质 -
public void greatTemperament(); -
}
-
public class PettyGirl implements IGoodBodyGirl,IGreatTemperamentGirl { -
private String name; -
//美女都有名字 -
public PettyGirl(String _name){ -
this.name=_name; -
} -
//脸蛋漂亮 -
public void goodLooking() { -
System.out.println(this.name + "---脸蛋很漂亮!"); -
} -
//气质要好 -
public void greatTemperament() { -
System.out.println(this.name + "---气质非常好!"); -
} -
//身材要好 -
public void niceFigure() { -
System.out.println(this.name + "---身材非常棒!"); -
} -
}
-
- 接口隔离原则是对接口进行规范约束,包含4层含义:接口要尽量小,但是不能违反单一职责原则;接口要高内聚;定制服务,就是单独为一个个体提供优良的服务;接口的设计师有限度的。
- 迪米特原则——Law Of Demeter
- 定义:一个对象应该对其他对象有最少的了解。通俗地讲,一个类应该对自己需要耦合或调用的类知道得最少,你(被耦合或调用的类)的内部是如何复杂都和我没关系,那是你的事情,我就知道你提供的这么多public方法,我就调用这么多,其他的我一概不关心。
- 迪米特法则告诉我们一个类只和朋友类交流。朋友类的定义是这样的:出现在成员变量、方法的输入输出参数中的类称为成员朋友类,而出现在方法体内部的类不属于朋友类。
- 一个类公开的public属性或方法越多,修改时涉及的面也就越大,变更引起的风险扩散也就越大。因此,为了保持朋友类间的距离,在设计时需要反复衡量:是否还可以再减少 public方法和属性,是否可以修改为private、package-private(包类型,在类、方法、变量前 不加访问权限则默认为包类型)、protected等访问权限,是否可以加上final关键字等。
-
- 如果一个方法放在本类中,既不增加类间关系,也对本类不产生负面影响,那就放置在本类中。
- 开闭原则——Open Close Principle
- 定义:软件中的对象(类、模块、函数等)应该对于扩展是开放的,但是对于修改是封闭的。程序一旦开发完成,程序中的一个类的实现只应该因错误而被修改,新的或者改变的特性应该通过新建不同的类实现,新建类可以通过继承的方式来重用原类代码。
-
- 使用开闭原则——抽象约束:第一,通过接口或抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的public方法;第二,参数类型、引用对象尽量使用接口或者抽象类,而不是实现类;第三,抽象层尽量保持稳定,一旦确定即不允许修改。
- 使用开闭原则——元数据控制模块行为:是尽量使用元数据来控制程序的行为,减少重复开发。元数据用来描述环境和数据的数据,通俗地说就是配置参数,参数可以从文件中获得,也可以从数据库中获得。通过扩展一个子类,修改配置文件,完成业务变化。
- 使用开闭原则——制定项目章程:章程中指定了所有人员都必须遵守的约定,对项目来说,约定优于配置。
- 使用开闭原则——封装变化::第一,将相同的变化封装到一个接口或抽象类中;第二,将不同的变化封装到不同的接口或抽象类中,不应该有两个不同的变化出现在同一个接口或 抽象类中。
作者:龙猫小爷
链接:http://www.jianshu.com/p/dbc8a279165d
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。