Open/Closed 原则和违反封装性
Posted
技术标签:
【中文标题】Open/Closed 原则和违反封装性【英文标题】:Open/Closed principle and violation of encapsulation 【发布时间】:2016-09-21 17:48:19 【问题描述】:请您检查以下代码是否正确?事实上,我在生产代码中发现了类似的东西,我怀疑它是否符合 Open/Closed 原则。
public abstract class CustomClass
private ClassThatSetEnvironmentProperty sysProp = new ClassThatSetEnvironmentProperty("SYS_PROPETY", "SYS_PROPERTY_VALUE");
// some code here
void setSysProp(ClassThatSetEnvironmentProperty sysProp)
this.sysProp = sysProp;
我的理解是 setter 仅用于单元测试可能性(模拟ClassThatSetEnvironmentProperty
)。但是在这种情况下,setter 允许具体的继承者改变定义的状态。从我的角度来看,它违反了封装。此外,我认为它也违反了开放/封闭原则。坦率地说,我的一些同事持相反的观点。我真的没有太多的经验,所以我很难认出它。请在这里分享您的意见。谢谢。
【问题讨论】:
我更喜欢构造函数注入而不是 setter 注入。 你是对的,我完全同意你的看法。但是目前的情况呢? Open/Closed 原则的定义指出,一个人应该能够在不修改其源代码的情况下改变一个类的行为。在这种情况下,我认为它完全没有违反原则。源代码保持不变,但sysProp
已更改。
当前案例使用setter注入;我会使用构造函数。你可以让它不可变而不破坏封装。
@christopher 好的,谢谢。但我的理解是ClassThatSetEnvironmentProperty
实例化是在抽象类中定义的,为继承者定义了一部分公共状态。如果属性可以更改,在每个具体类中定义它会更好吗?
【参考方案1】:
这与开闭原则没有直接关系,开闭原则只是意味着要向系统添加新行为,您应该创建一个新的实现类而不是更改旧的实现类。使用抽象类就可以了。
确实违反封装(这是一个不同的原则)的一件事是包可访问的依赖项设置器。您可以通过将其更改为受保护的设置器来解决该问题。然后扩展类可以设置自己的,但外部调用者不能改变你的对象的状态。
protected final void setSysProp(ClassThatSetEnvironmentProperty sysProp)
this.sysProp = sysProp;
【讨论】:
我同意。谢谢 Protected 比私有包更少限制(默认)。 @OleV.V.它们的限制不同。受保护确保所有扩展类都可以访问它。对于共享 API,这是一项关键要求。 @SilasReinagel,你我都没有完全理解Controlling Access to Members of a Class。以上是关于Open/Closed 原则和违反封装性的主要内容,如果未能解决你的问题,请参考以下文章