开放/封闭原则是否说我们不能改变我们类的接口?

时间:2016-04-03 06:49:17

标签: java oop solid-principles

请看这堂课:

public class SomeClass {

public void method1(){
    // do something
}

public void method2(){
    // do something
}

}

接下来,假设有10个类继承了这个类。因此,如果我们将parametr添加到method1(),例如我们必须更改10个类。这与开放/封闭原则相反。那么,开放/封闭原则是否说我们不能改变我们类的公共接口?

2 个答案:

答案 0 :(得分:0)

是 - 有点...... #8> P

"关闭更改" 位表示您不应删除public void method1()签名,也不应更改其语义(由所有正确实现的具体类提供)。

"打开扩展名" 位允许您(小心)修改界面,只要前面的界面元素保持原样(结构上和语义上)。您可以尝试这样的事情:

public class SomeClass {

    @Deprecated
    default public void method1(){
        method1(#SENTINAL#);
    }

    public void method1(#TYPE# arg){
        if (arg == #SENTINAL#) {
            // do something old
        } else {
            // do something new
        }
    }

    public void method2(){
        // do something
    }

}

注意:如果参数没有有用的 #SENTINAL#值,则此方法可能无效,例如:它是int,所有值都有效。但是,通常有一些东西,比如任何负面的,MIN或MAX值,空或空对象等。当没有这样的sentinal可用时,你可以创建一个私有的公共方法,如:

public class SomeClass {

    @Deprecated
    default public void method1(){
        method1(true);
    }

    public void method1(#TYPE# arg){
        method1(false, arg)
    }

    private void method1(boolean isOldWay, #TYPE# arg) {
        if(isOldWay) {
            // snore - still old clients
        } else {
            // yea! new clients are much greener!
        }
    }
}

PS - 我说"界面"即使你正在上课。只需将接口视为类的公共元素,在实现类的同时声明。我通常更喜欢代码到接口,但这不是OP的问题,也不会改变我的观点(仅仅是 修改的地方 - 尤其是使用Java时8个接口默认实现)。

答案 1 :(得分:0)

违反了OCP。 接近修改意味着一旦您实现了类并对其进行了测试,就不应再修改它了。 有一些不可预测的情况,业务需求突然发生变化,无论您如何设计它们,都必须修改您的类。 在你的情况下,最简单的方法是通过将它注入实现类的构造函数来添加这个新参数,或者更好的是,注入这个参数的提供者

public class SomeClass{       
    IProvider _provider;

    public SomeClass(IProvider provider){
        _provider = provider
    }

    public void method1(){
        var someInput = _provider.Get();
        // do something
    }

    public void method2(){
        var someInput = _provider.Get();
        // do something
    }
}