那些你要知道的设计原则之-开闭原则

2018-04-22  本文已影响62人  小巨人Vea

1.定义

1.一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。
对组建的功能扩展是开放的,对原有代码的修改是封闭的

是面向对象设计的核心,是最基础的一个原则,其他五种设计原则都是针对于开闭原则的实现方式和方法

2.作用

3.案例

以LOL 选英雄为例子,提供英雄英雄,符文,天赋三个属性,具体的实现类CommonRole

/**
 * 角色
 */
public interface IRole {

        //英雄
        String getHero();

        //符文
        String getFuWen();

        //天赋
        String getGenius();

}

public class CommonRole implements IRole {

    //英雄
    private String hero;
    //符文
    private String fuWen;
    //天赋
    private String genius;


    public CommonRole(String hero, String fuWen, String genius) {
        this.hero = hero;
        this.fuWen = fuWen;
        this.genius = genius;
    }

    @Override
    public String getHero() {
        return hero;
    }

    @Override
    public String getFuWen() {
        return fuWen;
    }

    @Override
    public String getGenius() {
        return genius;
    }
}

写一个Main函数打印其内容

public class Main {


    public static void main(String[] args) {
        List<IRole>  role = new ArrayList<>();
        role.add(new CommonRole("盖伦","全肉符文","全肉天赋"));

        System.out.println("英雄:"+role.get(0).getHero());
        System.out.println("符文:"+role.get(0).getFuWen());
        System.out.println("天赋:"+role.get(0).getGenius());
    }
}

打印结果如下:
英雄:盖伦
符文:全肉符文
天赋:全肉天赋

随着项目的发展,在选择角色的这个环节增加了皮肤这个选项,那么本着开闭原则不可能在原有的接口中增加皮肤这个选择,如果在原有的接口上增加,不仅要修改接口,实现类,业务逻辑也要发生变化,最好的方式是对组建功能进行扩展,修改如下:

public interface ISkinRole  extends IRole{

        //皮肤
        String getSkin();
}

在原有基础上增加ISkin接口,对应的实现类Skin

public class SkinRole implements ISkinRole {

    //英雄
    private String hero;
    //符文
    private String fuWen;
    //天赋
    private String genius;
    //皮肤
    private String skin;

    public SkinRole(String hero, String fuWen, String genius, String skin) {
        this.hero = hero;
        this.fuWen = fuWen;
        this.genius = genius;
        this.skin = skin;
    }

    @Override
    public String getSkin() {
        return skin;
    }

    @Override
    public String getHero() {
        return hero;
    }

    @Override
    public String getFuWen() {
        return fuWen;
    }

    @Override
    public String getGenius() {
        return genius;
    }
}

在main函数中新增加一条数据

   public static void main(String[] args) {
        List<IRole>  role = new ArrayList<>();
        role.add(new CommonRole("盖伦","全肉符文","全肉天赋"));
        role.add(new SkinRole("剑圣","攻击符文","攻击天赋","天人合一皮肤"));

        System.out.println("英雄:"+role.get(0).getHero() +" 符文:"+role.get(0).getFuWen()+" 天赋:"+role.get(0).getGenius());
        System.out.println("英雄:"+role.get(1).getHero() +" 符文:"+role.get(1).getFuWen()+" 天赋:"+role.get(1).getGenius());


    }

打印结果如下:
英雄:盖伦 符文:全肉符文 天赋:全肉天赋
英雄:剑圣 符文:攻击符文 天赋:攻击天赋

OK!在没有修改其他业务就实现了对皮肤功能的扩展,完成了业务的变化。

4.总结

抽象层尽量保持稳定,一旦确定就不要修改,参数类型、引用对象尽量使用接口或者抽象类,而不是实现类。掌握并运用好设计模式,将轻松的适应不同的变化。

上一篇下一篇

猜你喜欢

热点阅读