设计模式原则
开闭原则
开放封闭原则(OCP, Open Closed Principle)
定义为:一个软件实例,如类、模块、函数等应该对外扩展开放,而对修改封闭;
对扩展开放:当有新的需求或变化时,可以对现有的代码进行扩展,以适应新的情况;
对修改封闭:当类设计完成,就可以独立完成其工作,而不需要对其已有代码进行任何修改;
用抽象构建框架,使用实现扩展细节;
这也是容易维护且不容易出问题的最好办法:多扩展,少修改;
核心思想是 面对抽象编程:
类依赖于固定的抽象,因此对修改是封闭的;
通过面向对象的继承和多态机制,可以实现对抽象体的继承,通过重写方法来改变原有行为,实现新的扩展方法,因此对扩展是开放的;
如何落实开闭原则:
抽象约束
通过接口或者抽象类的约束,对扩展进行边界限定,规定实现的方法,不允许出现除抽象方法实现外的公开方法;
对于使用的参数类型,应该使用其接口或者抽象类,而不是实现类;
抽象层应该尽量保持稳定,不会随便变化;
封装变化:
将相同的变化封装到一个接口或抽象类中(将同一种但有不同实现的功能抽离出来)
将不同的变化封装到不同的接口或抽象类中,不应该有两个不同的变化出现在同一个接口或抽象类中;(不同的功能应该分开来抽离)
举个例子:
存在一个文件操作,可以 zip 或 gz 压缩,进行 base64 加密(编码)或 rsa 加密:
class FileOperators {
String zipCompress(String data) {
return "zipped: " + data;
}
String gzCompress(String data) {
return "gz: " + data;
}
String base64Encrypt(String data) {
return "base64Encrypt: " + data;
}
String rsaEncrypt(String data) {
return "rsaEncrypt: " + data;
}
}如果要添加新的功能,就需要修改上面的类代码,添加一个 xxxCompress 或者 xxxEncrypt 方法,这样就违背了对修改封闭;
将相同的变化抽离出来,在上面的例子中, compress 是相同的变化,encrypt 是另一相同变化,因此可以将其抽离出来为一个接口分别进行实现:
将相同变化的
compress单独封装到Compressible中;将不同变化的
compress和encrypt分别封装到不同的接口中,而不是同一个接口有这两种变化;
interface Compressible {
String compress(String data);
}
class ZipCompress implements Compressible {
@Override
public String compress(String data) {
return "zipped: " + data;
}
}
class GzCompress implements Compressible {
@Override
public String compress(String data) {
return "gz: " + data;
}
}
interface Encryptable {
String encrypt(String data);
}
class Base64Encrypt implements Encryptable {
@Override
public String encrypt(String data) {
return "Base64Encrypt: " + data;
}
}
class RSAEncrypt implements Encryptable {
@Override
public String encrypt(String data) {
return "RSAEncrypt: " + data;
}
}
class FileOperators {
String compress(Compressible compressible, String data) {
return compressible.compress(data);
}
String encrypt(Encryptable encryptable, String data) {
return encryptable.encrypt(data);
}
}该更改后的代码中,当添加了一种新的压缩方式时,只需要实现 Compressible 接口即可,而不需要修改其他地方的代码;
这就是对扩展开放,对修改封闭;
创建型设计模式
待更新....
行为型设计模式
待更新....