设计模式之 开放封闭原则

开放-封闭原则(Open Closed Principle),是说软件实体(类、模块、函数等)应该可以扩展,但是不可修改。(多扩展,少修改)

  对扩展开放:有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。

  对修改封闭:类一旦设计完成,就可以独立其工作,而不要轻易对类做修改。

如何做到对扩展开放,对修改封闭呢?

      实现开放封闭的核心思想就是对抽象编程,而不对具体编程,因为抽象相对稳定。让类依赖于固定的抽象,所以对修改就是封闭的;而通过面向对象的继承和多态机制,可以实现对抽象体的继承,通过覆写其方法来改变固有行为,实现新的扩展方法,所以对于扩展就是开放的。

      对于违反这一原则的类,必须通过重构来进行改善。常用于实现的设计模式主要有Template Method模式和Strategy 模式。而封装变化,是实现这一原则的重要手段,将经常变化的状态封装为一个类。

 

场景:公司部分员工离家太远,9点上班打卡经常迟到,为了照顾这部分员工,公司推出弹性工作制,每天只要工作小时数够了就可以。

分析:制度的推行实现了 对每天工作总时长的修改关闭,对上班打卡时间开放扩展。

 

我们不实现OCP的设计代码:

public class WorkPunchCard {
    //9点打卡
    public void PunchCardNine(){
        System.out.println("6点下班");
    }
    //10点打卡
    public void PunchCardTen(){
        System.out.println("7点下班");
    }
}

public class Employee {
    private WorkPunchCard wpc = new WorkPunchCard();

    public void OffDuty(int type) {
        switch (type){
            case 9:
                wpc.PunchCardNine();
                break;
            case 10:
                wpc.PunchCardTen();
                break;
        }
    }
}

如果现在老板说 来的早的8点打卡的可以下午5点下班,那么我们上面的代码耦合性就太高了,每个类都需要修改。

 

那我们就需要通过继承和多态来改造我们上面的代码,以达到对修改封闭,对扩展开放:

/**
 * 定义顶层接口
 */
public interface IWorkPunchCard {
    //打卡的抽象方法
    void PunchCard();
}

/**
 * 具体类实现接口
 */
public class PunchCardEight implements IWorkPunchCard {
    @Override
    public void PunchCard() {
        System.out.println("8点上班,5点下班");
    }
}
public class PunchCardNine implements IWorkPunchCard {
    @Override
    public void PunchCard() {
        System.out.println("9点上班,6点下班");
    }
}
public class PunchCardTen implements IWorkPunchCard {
    @Override
    public void PunchCard() {
        System.out.println("10点上班7点下班");
    }
}

public class Employee {

    public void OffDuty(int type) {
        IWorkPunchCard iwpc = null;
        switch (type){
            case 8:
                iwpc = new PunchCardEight();
                break;
            case 9:
                iwpc = new PunchCardNine();
                break;
            case 10:
                iwpc = new PunchCardTen();
                break;
        }
        iwpc.PunchCard();
    }
}

如此一来,当再次增加10点或其他时间打卡的时候,我们只需要扩展几点打卡的类和修改业务的实现就可以了,做到了对其他类的修改封闭,对打卡时间开放了扩展。

 

上面只是简单的一个案例,这种设计模式的原则其实也是一种思想,在什么地方适用,什么地方不适用还需多多磨炼,细细斟酌。

posted @ 2017-06-27 21:06  青衫仗剑  阅读(361)  评论(0编辑  收藏  举报