Skip to content

开闭原则 #9

@bitfishxyz

Description

@bitfishxyz

开闭原则

对扩展开发,对修改封闭

其实这里主要的问题是修改之前的代码,可能会导致依赖当前代码的程序发生逻辑错误,我们应该尽量的扩展而不是修改。

现实中比较类似的是社交论坛中的留言功能,很多的论坛都会禁止用户修改之前的发言。这里主要的考量就是在用户A留言后,别人可能会根据A的留言进行回复。如果A修改的自己的留言,那么很有可能就会导致其他人的回复失效,使得第三方看起来有点莫名其妙。当然这个原则也会有些弊端,就是可能导致很多低级的错误比如拼写错误得不到纠正。

下面我们具体来看下代码。

这是一个简单的Java程序

interface ICar{
    void start();
}

class Tesla implements ICar{
    @Override
    public void start(){
        System.out.println("Tesla runs");
    }
}

public class Test {
    public static void main(String[] args) {
        ICar car = new Tesla();
        car.start();
    }
}

我们的接口ICar定义了汽车的一个基本功能:start。然后Tesla类实现了这个接口。接着我们在Test类中new了一个Tesla,并且启动了它。

然后现在我们有个需求,就是Tesla公司决定给Tesla汽车安装上🚀🚀。这样我们start的时候就不是在马路上跑了,而是直接飞到天上去了。
如果要实现这样的效果,我们应该怎么样修改自己的代码。

方案一:直接修改Tesla类

class Tesla implements ICar{
    @Override
    public void start(){
        System.out.println("Tesla 飞了");
    }
}

这样做行不行呢?语法上当然没有问题,但是缺点非常明显:我们直接修改了Tesla的方法,可能导致其他使用到这个类的地方出现逻辑错误。同时万一我们以后取消了这个功能的话,又需要修改回来,增加了出bug的几率。
这个方案不建议使用。

方案二:在ICar中添加fly方法

interface ICar{
    void start();
    void fly();
}

class Tesla implements ICar{
    @Override
    public void start(){
        System.out.println("Tesla runs");
    }
    @Override
    public void fly(){
        System.out.println("Tesla runs");
    }
}
public class Test {
    public static void main(String[] args) {
        ICar car = new Tesla();
        car.fly();
    }
}

这个的缺点是直接修改了接口,使得其他所有的实现类都要改动。虽然我们可以使用接口的default方法解决这个问题,但是不是所有的汽车都安装了火箭啊。

但是有的同学想了,这个fly方法我不写到接口里面,只写到Tesla类中行不行?

interface ICar{
    void start();
}

class Tesla implements ICar{
    @Override
    public void start(){
        System.out.println("Tesla runs");
    }
    public void fly(){
        System.out.println("Tesla runs");
    }
}
public class Test {
    public static void main(String[] args) {
        ICar car = new Tesla();
        car.fly();
    }
}

其实这样我个人是觉得也可以啊,不过看起来不符合开放封闭原则。

方案三:为Tesla类编写一个子类,来扩展我们的功能

interface ICar{
    void start();
}

class Tesla implements ICar{
    @Override
    public void start(){
        System.out.println("Tesla runs");
    }
}

class TeslaWithRocket extends Tesla{
    @Override
    public void start(){
        super.start();
        System.out.println("特斯拉飞了");
    }
}

public class Test {
    public static void main(String[] args) {
        ICar car = new TeslaWithRocket();
        car.start();
    }
}

我们不需要修改之前的类或者接口,就可以扩展功能。

这就是开发封闭原则的体现。

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions