趣话-开闭原则

开闭原则


在面向对象编程领域中,开闭原则要求软件对象应该对扩展开放,对修改关闭。即,一个实体在不修改其原有代码的基础上,为其增添新的功能或改变其行为。

举个例子,现有一个砸金蛋的活动,顾客可以选择工具来砸开金蛋,获得奖励。我们为顾客准备了一把锤子,顾客使用锤子砸开金蛋,获得奖励。

首先,不使用设计模式以及开闭原则的方式来为其编码。

硬编码

  • 定义锤子类,需要敲击三次才能砸开金蛋
    //锤子工具
    public class HammerTool {
        private string toolName = "锤子";
        private int count = 3;
        //敲击
        public void Rap () {
            for (int i = 0; i < count; i++) {
                Console.WriteLine (toolName + ":第{0}次", i);
            }
        }
    }
  • 定义顾客类,顾客使用工具砸开金蛋
    //顾客
    public class User {
        private HammerTool _hammerTool;
        public User (HammerTool hammerTool) {
            _hammerTool = hammerTool;
        }
        //使用工具
        public void UseTool () {
            _hammerTool.Rap ();
        }
    }
  • 客户端调用
 class Program {
        static void Main (string[] args) {
            var user = new User (new HammerTool ());
            user.UseTool ();
        }
    }
  • 输出
锤子:第0次
锤子:第1次
锤子:第2次

好了,通过硬编码的砸金蛋活动完成了。过了几天,活动方反应,这个活动还不错,参与人数也挺多,现在他们需要增加一个工具———斧子,好吧,按照我们正常的逻辑,当然是去修改代码咯,这里还是使用硬编码实现。

硬编码——增加斧子

  • 定义斧子类,只需要敲击一次就可以砸开金蛋
    //斧子工具
    public class HatChetTool {
        private string toolName = "斧子";
        private int count = 0;
        public void Rap () {
            Console.WriteLine (toolName + ":第{0}次", count);
        }
    }
  • 原先的User类已经不适用于当前的斧子工具了,需要重新修改User类适应当前工具;好吧,很烦
 public class NewUser{
        private HatChetTool _hatChetTool;
        public NewUser (HatChetTool hatChetTool) {
            _hatChetTool = hatChetTool;
        }
        //使用工具
        public void UseTool () {
            _hatChetTool.Rap ();
        }
    }
  • 客户端调用
static void Main (string[] args) {

        User user=new User(new HammerTool());
        user.UseTool();

        NewUser newUser=new NewUser(new HatChetTool());
        newUser.UseTool();
    }
  • 输出
锤子:第0次
锤子:第1次
锤子:第2次
斧子:第0次

任务终于完成了,可是总感觉哪里说不出来的不对劲,先休息吧。叮铃铃,叮铃铃,叮铃铃,叮铃铃,叮铃铃。 活动方来电话了,这个活动太火爆了,骗了不少老人和小孩的钱。现在还要再加几个工具。哎呦,难受。。。。算了,试试设计模式吧。

首先分析一下当前的需求,我们的目标是使用不同的工具砸开金蛋,各个工具的使用方式都不同,比如锤子要敲击三次,而斧子只需要敲击一次;活动方会时不时的增加不同的工具。那么,我们是不是可以把工具抽象出来,在客户端中使用抽象,而不是使用具体的工具类和客户端交互。

使用开闭原则

  • 为所有的工具类定义一个接口
public interface IBaseTool {
        void Rap ();
    }
  • 锤子工具
    //锤子工具
    public class HammerTool : IBaseTool {
        private string toolName = "锤子";
        private int count = 3;
        public void Rap () {
            for (int i = 0; i < count; i++) {
                Console.WriteLine ("{0} : 第{1}次", toolName, i+1);
            }
        }
    }
  • 斧子工具
     //斧子工具
    public class HatChetTool : IBaseTool {
        private string toolName = "斧子";
        private int count = 1;
        public void Rap () {
            Console.WriteLine ("{0} : 第{1}次",toolName,count);
        }
    }
  • 顾客类
//顾客
    public class User {
        private IBaseTool _baseTool;
        public User (IBaseTool baseTool) {
            _baseTool = baseTool;
        }
        public void UserTool () {
            _baseTool.Rap ();
        }
    }
  • 客户端调用
class Program {
        static void Main (string[] args) {

            User user_01 = new User (new HammerTool ());
            user_01.UserTool ();

            User user_02 = new User (new HatChetTool ());
            user_02.UserTool ();
        }
    }
  • 输出
锤子 : 第1次
锤子 : 第2次
锤子 : 第3次

斧子 : 第1次

完成,要休息了。呼呼呼…,呼呼呼…,呼呼呼…,呼呼呼…,呼呼呼…,呼呼呼…,呼呼呼…,呼呼呼…,呼呼呼…

叮铃铃…叮铃铃…叮铃铃…叮铃铃…叮铃铃…叮铃铃…叮铃铃…叮铃铃…叮铃铃…

活动方:现在老人和小孩学精明了,没那么好骗了,我们推出了一个新的工具————绣花针;要求,绣花针要戳一千次才能砸开金蛋。好吧,虽然满腹罪恶,心有不甘,还是闭着眼睛为活动方增加了这样的需求。

  • 增加绣花针工具
public class EmbroideryNeedle : IBaseTool {
        private string toolName = "绣花针";
        private int count = 1000;
        public void Rap () {
            Console.WriteLine ("黑心无量活动方");
            for (int i = 0; i < count; i++) {
                Console.WriteLine ("{0} : 第{1}次", toolName, i + 1);
            }
        }
    }
  • 客户端调用
class Program {
        static void Main (string[] args) {

            User user_01 = new User (new HammerTool ());
            user_01.UserTool ();

            User user_02 = new User (new HatChetTool ());
            user_02.UserTool ();

            User user_03 = new User (new EmbroideryNeedle ());
            user_03.UserTool ();
        }
    }
  • 输出,太长了,自己控制台打去吧

总结:开闭原则,对扩展开放,对修改关闭。当有新的需求增加时,我们不对原有的代码做任何的修改,只增加新的需求,并在客户端增加对应的调用方式。

猜你喜欢

转载自blog.csdn.net/JianZuoGuang/article/details/89448409
今日推荐