C#开放和封闭原则

来源:互联网 发布:网络舆情监控的重要性 编辑:程序博客网 时间:2024/06/09 20:59

Software entities(classes,modules,functions etc) should open for extension ,but close for modification.

   什么意思呢?

   所谓开放封闭原则就是软件实体应该对扩展开发,而对修改封闭。开放封闭原则是所有面向对象原则的核心。软件设计本身所追求的目标就是封装变化,降低耦合,而开放封闭原则正是对这一目标的最直接体现。

   开放封闭原则主要体现在两个方面:

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

   对修改封闭,意味着类一旦设计完成,就可以独立其工作,而不要对类尽任何修改。

 

为什么要用到开放封闭原则呢?

软件需求总是变化的,世界上没有一个软件的是不变的,因此对软件设计人员来说,必须在不需要对原有系统进行修改的情况下,实现灵活的系统扩展。

 

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

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

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

以银行业务员为例

没有实现OCP的设计:

public class BankProcess

    {  //存款 

       public void Deposite(){}

        //取款

        public void Withdraw(){ }

        //转账

        public void Transfer(){}

    }

    public class BankStaff

    {

        private BankProcess bankpro = new BankProcess();

        public void BankHandle(Client client)

        {

            switch (client.Type)

            {  //存款

                case "deposite":

                    bankpro.Deposite();

                    break;

                    //取款

                case "withdraw":

                    bankpro.Withdraw();

                    break;

                    //转账

                case "transfer":

                    bankpro.Transfer();

                    break;

            }

        }

    }

     这种设计显然是存在问题的,目前设计中就只有存款,取款和转账三个功能,将来如果业务增加了,比如增加申购基金功能,理财功能等,就必须要修改BankProcess业务类。我们分析上述设计就不能发现把不能业务封装在一个类里面,违反单一职责原则,而有新的需求发生,必须修改现有代码则违反了开放封闭原则。

      从开放封闭的角度来分析,在银行系统中最可能扩展的就是业务功能的增加或变更。对业务流程应该作为扩展的部分来实现。当有新的功能时,不需要再对现有业务进行重新梳理,然后再对系统做大的修改。

如何才能实现耦合度和灵活性兼得呢?

那就是抽象,将业务功能抽象为接口,当业务员依赖于固定的抽象时,对修改就是封闭的,而通过继承和多态继承,从抽象体中扩展出新的实现,就是对扩展的开放。

以下是符合OCP的设计:

首先声明一个业务处理接口

public  interface IBankProcess{  void Process();}

public class DepositProcess : IBankProcess

    {

        public void Process()

        { //办理存款业务

            Console.WriteLine("Process Deposit");

        }

}

public class WithDrawProcess : IBankProcess

    {

        public void Process()

        { //办理取款业务

            Console.WriteLine("Process WithDraw");

        }

}

public class TransferProcess : IBankProcess

    {

        public void Process()

        { //办理转账业务

            Console.WriteLine("Process Transfer");

        }

    }

public class BankStaff

    {

        private IBankProcess bankpro = null;

        public void BankHandle(Client client)

        {

            switch (client.Type)

            {   //存款

                case "Deposit":

                    userProc = new DepositUser();

                    break;

                    //转账

                case "Transfer":

                    userProc = new TransferUser();

                    break;

                    //取款

                case "WithDraw":

                    userProc = new WithDrawUser();

                    break;

            }

            userProc.Process();

        }

    }

 

这样当业务变更时,只需要修改对应的业务实现类就可以,其他不相干的业务就不必修改。当业务增加,只需要增加业务的实现就可以了。

 

设计建议:

开放封闭原则,是最为重要的设计原则,Liskov替换原则和合成/聚合复用原则为开放封闭原则提供保证。

可以通过Template Method模式和Strategy模式进行重构,实现对修改封闭,对扩展开放的设计思路。

封装变化,是实现开放封闭原则的重要手段,对于经常发生变化的状态,一般将其封装为一个抽象,例如银行业务中IBankProcess接口。

拒绝滥用抽象,只将经常变化的部分进行抽象。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 我的电脑打cffps不稳定怎么办 生米煮成了熟饭该怎么办 做完下蹲腿疼该怎么办 下蹲腿的筋酸痛怎么办 躺平了 腿酸痛怎么办 500上下蹲后腿痛怎么办 蹲完马步后站不起来怎么办? 车在水里熄火了怎么办 脚磕到了很疼怎么办 破腹产4年了腰疼怎么办 蹲起之后腿疼怎么办 深蹲起跳伤腰部怎么办 蹲起膝盖有响声怎么办 腰突然不能弯了怎么办 蚂蚱吃了会过敏怎么办 孕妇能吃蚂蚱菜怎么办 孕妇吃了蚂蚁菜怎么办 白果很硬的时候怎么办 有痔疮吃了胡椒怎么办 吃紫菜多了难受怎么办 四川泡菜太酸了怎么办 孕妇吃了白花菜怎么办 怀孕吃了马扎菜怎么办 被铁钉扎伤了脚怎么办 风扇吹得肩膀疼怎么办 胳膊肌肉那块肿了怎么办 生完孩子臀部变宽怎么办 3岁宝宝肋骨外翻怎么办 胸肌正面不明显侧面看才有怎么办 小孩胸肌骨突出外翻怎么办 衣柜隔层板坏了怎么办 科三路线记不住怎么办 喂奶以后胸变小了怎么办 健身完肩膀缝疼怎么办 生过孩子胯部宽怎么办 无肩带文胸往下滑怎么办 内衣肩带老是往下滑怎么办 乳房发育一边大一边小怎么办 母猫乳房有硬块怎么办 19岁乳晕很大乳头很小怎么办 做完俯卧撑胳膊特别痛怎么办