=================================================================
没有将实现变化封装在抽象和层次结构中时,将导致这种坏味。
表现形式通常如下:
-
客户程序与其需要的服务变种紧密耦合,每当需要支持新变种或修改既有变种时,都将影响客户程序。
-
每当需要在层次结构中支持新变种时,都添加了大量不必要的类,这增加了设计的复杂度。
开闭原则(OCP)指出,类型应对扩展开放,对修改关闭。也就是说应该通过扩展(而不是修改)来改变类型的行为。没有在类型或层次结构中封装实现变化时,便违反了OCP。
未意识到关注点会不断变化[](
)
没有预测到关注点可能发生变化,进而没有在设计中正确封装这些关注点。
混合关注点[](
)
将彼此独立的各个关注点聚合在一个层次结构中,而不是分开时,如果关注点发生变化,可能导致类的数量呈爆炸式增长。
幼稚的设计决策[](
)
采用过于简单的方法,如为每种变化组合创建一个类时,可能导致设计无谓的复杂。
假设有一个Entryption类,它需要使用加密算法对数据进行加密。可供选择的加密算法有很多,包括DES(数据加密标准)、AES(高级加密标准)、TDES(三重数据加密标准)等。Entryption类使用DES算法对数据进行加密。
public class Encryption
{
/// <summary>
/// 使用DES算法进行加密
/// </summary>
public void Encrypt() {
// 使用DES算法进行加密
}
}
假设出现了新需求,要求使用AES算法对数据进行加密。
最差的方案出现了:
public class Encryption
{
/// <summary>
/// 使用DES算法进行加密
/// </summary>
public void EncryptUsingDES() {
// 使用DES算法进行加密
}
/// <summary>
/// 使用AES算法进行加密
/// </summary>
public void EncryptUsingAES() {
// 使用AES算法进行加密
}
}
这种方案有很多不尽如人意的地方:
-
Encryption类变得更大、更难以维护,因为它实现了多种加密算法,但是每次只使用一种。
-
难以添加新算法以及修改既有算法,因为加密算法是Encryption类不可分割的部分。
-
加密算法向Encryption类提供服务,但是与Encryption类紧紧耦合在一起,无法在其它地方重用。
不满意就重构,首先使用继承进行重构,会有2种方案可以选择:
选择1:
让Encryption类根据需求继承AESEncryptionAlgorithm或DESEncryptionAlgorithm类,并提供方法Encrypt()。这种方案带来的问题是Encryption类在编译阶段就将关联到特定的加密算法,更严重的是类之间的关系并不是is-a关系。
/// <summary>
/// AES算法加密类
/// </summary>
public class AESEncryptionAlgorithm
{
/// <summary>
/// 使用AES算法进行加密
/// </summary>
public void EncryptUsingAES() {
// 使用AES算法进行加密
}
}
/// <summary>
/// DES算法加密类
/// </summary>
public class DESEncryptionAlgorithm
{
/// <summary>
/// 使用DES算法进行加密
/// </summary>
public void EncryptUsingDES() {
// 使用DES算法进行加密
}
}
public class Encryption: AESEncryptionAlgorithm
{
/// <summary>
/// 使用算法进行加密
/// </summary>
public void Encrypt() {
EncryptUsingAES();
}
}
选择2:
创建子类AESEncryption和DESEncryption,它们都扩展了Encryption类,并分别包含加密算法AES和DES的实现。客户程序可创建Encryption的引用,这些引用指向特定子类的对象。通过添加新的子类,很容易支持新的加密算法。但是这种方案的问题是AESEncryption和DESEncryption将继承Encryption类的其它方法,降低了加密算法的可重用性。
public abstract class Encryption
{
/// <summary>
/// 使用算法进行加密
/// </summary>
public abstract void Encrypt();
}
/// <summary>
/// AES算法加密类
/// </summary>
public class AESEncryption : Encryption
{
/// <summary>
/// 使用 AES算法进行加密
/// </summary>
public override void Encrypt() {
// 使用 AES算法进行加密
}
}
/// <summary>
/// DES算法加密类
/// </summary>
public class DESEncryption : Encryption
{
/// <summary>
/// 使用 DES算法进行加密
/// </summary>
public override void Encrypt() {
// 使用 DES算法进行加密
}
}
最佳的选择是使用策略模式:
-
可在运行阶段给Encryption对象配置特定的加密算法
-
可在其它地方重用层次结构EncryptionAlgorithm中定义的算法
最后
针对以上面试题,小编已经把面试题+答案整理好了
面试专题
除了以上面试题+答案,小编同时还整理了微服务相关的实战文档也可以分享给大家学习
echina.csdn.net/m0_60958482/java-p7)**
[外链图片转存中…(img-GOuu6roV-1630666911685)]
[外链图片转存中…(img-JouRujdp-1630666911687)]
[外链图片转存中…(img-TMag7geC-1630666911688)]
面试专题
[外链图片转存中…(img-XD1Ljdmi-1630666911690)]
除了以上面试题+答案,小编同时还整理了微服务相关的实战文档也可以分享给大家学习
[外链图片转存中…(img-1rxSf3HS-1630666911691)]
[外链图片转存中…(img-8lbFjpIW-1630666911692)]