码迷,mamicode.com
首页 > 其他好文 > 详细

To IOC,代码结构演变

时间:2016-08-18 12:55:25      阅读:272      评论:0      收藏:0      [点我收藏+]

标签:

代码结构演变

需求描述:

需求: 提供一个系统,可以在新春佳节之际以邮件的形式给员工发送新春祝福。

源自: 【调侃】IOC前世今生@家住腊树下

版本一

string message = "新年快乐!过节费5000.";
Console.Write("Frome email: " + message);

版本二

业务逻辑控制代码

string message = "新年快乐!过节费5000.";
EmailHelper emailHelper = new EmailHelper();
emailHelper.Send(message);

邮件发送

public class EmailHelper
{
     public void Send(string msg)
     {
         Console.Write("Frome email: " + msg);
     }
}

ps: 将邮件发送的业务代码封装掉(正常的邮件发送代码量还是有很多行的),使代码变得更清晰易改点。

需求变更

需求变更:要求增加发短信的方式,以便可以灵活选择。

祝福消息的发送方式不再是单一模式,要可以发邮件、也可以发短信、甚至后面随着时代的发展,还可能会逐步加入新的方式,如微信消息,微信公共号消息……

版本三

消息发送方式

public class EmailHelper
{
    public void Send(string msg)
    {
        Console.Write("Frome email: " + msg);
    }
}

public class SMSHelper
{
    public void Send(string msg)
    {
        Console.Write("Frome SMS: " + msg);
    }
}

消息发送服务类

public class GreetMessageService
{
    public enum SendType
    {
        Email,
        SMS,
    }
    public void Greet(string msg, SendType sendType)
    {
        switch (sendType)
        {
            case SendType.Email:
                EmailHelper emailHelper = new EmailHelper();
                emailHelper.Send(msg);
                break;
            case SendType.SMS:
                SMSHelper sMSHelper = new SMSHelper();
                sMSHelper.Send(msg);
                break;
        }
    }
}

业务逻辑控制代码

string message = "新年快乐!过节费5000.";
GreetMessageService service = new GreetMessageService();
service.Greet(message, GreetMessageService.SendType.Email);

PS:为了应该需求的变化,代码结构再次做了调整

当再次增加消息发送方式时,需要修改 GreetMessageService类 。

消息发送方式不用改动旧代码,仅扩展。

版本四

将消息发送方式,消息发送服务类这两个模块 各自建立独立的类库,分别开发,以组件的形式集成到项目中来。这样就可以交给张三、李四、王五各自独立去开发这三个模块。

其中:由张三负责业逻辑控制模块 LogicController的开发,此处简化为UT.LogicController.exe ;由李四负责祝福消息管理类(GreetMessageService),并集成到组件 UT.MessageService.dll中;由王五负责消息发送帮助类,并提供组件 UT.Email.dll。

技术分享

消息发送模块

namespace UI.Sendable
{
    public class EmailHelper
    {
        public void Send(string msg)
        {
            Console.Write("Frome email: " + msg);
        }
    }

    public class SMSHelper
    {
        public void Send(string msg)
        {
            Console.Write("Frome SMS: " + msg);
        }
    }
}

消息发送服务模块

using UI.Sendable;

namespace UI.MessageService
{
    public class GreetMessageService
    {
        public enum SendType
        {
            Email,
            SMS,
        }
        public void Greet(string msg, SendType sendType)
        {
            switch (sendType)
            {
                case SendType.Email:
                    EmailHelper emailHelper = new EmailHelper();
                    emailHelper.Send(msg);
                    break;
                case SendType.SMS:
                    SMSHelper sMSHelper = new SMSHelper();
                    sMSHelper.Send(msg);
                    break;
            }
        }
    }
}

业务逻辑控制模块

string message = "新年快乐!过节费5000.";
GreetMessageService service = new GreetMessageService();
service.Greet(message, GreetMessageService.SendType.Email);

版本五

因为考虑到以后可能再添加新的祝福方式,这种未来的不确定性,一定会让李四现有的枚举SendType和 GreetMessageService中的构造函数不断的进行更改,这将会是一个没完没了工作。

     再说了,既然张三要传SendToolType给我,也就是说在具体产品应用时,张三的模块肯定是知道要采用什么方式进行祝福,那么何不让他直接把祝福方式的实例而不是简单的方式类型给我呢?这样,我不就省事了吗,于是乎把设计进行了优化。

     ②、优化后设计方案:

   技术分享

消息发送模块

using System;

namespace UI.Sendable
{
    public interface ISendable
    {
        void Send(string message);
    }
    public class EmailHelper : ISendable
    {
        public void Send(string msg)
        {
            Console.Write("Frome email: " + msg);
        }
    }

    public class SMSHelper : ISendable
    {
        public void Send(string msg)
        {
            Console.Write("Frome SMS: " + msg);
        }
    }
}

消息发送服务模块

using UI.Sendable;

namespace UI.MessageService
{
    public class GreetMessageService
    {
        private ISendable sendHelper;
        public GreetMessageService(ISendable sendHelper)
        {
            this.sendHelper = sendHelper;
        }

        public void Greet(string msg)
        {
            sendHelper.Send(msg);
        }
    }
}

业务逻辑控制模块

string message = "新年快乐!过节费5000.";
ISendable greetTool = new EmailHelper();
GreetMessageService service = new GreetMessageService(greetTool);
service.Greet(message);

 

PS:

李四此处成功的利用“接口分离”、并结合“依赖倒置”的方式,使得自己负责的模块初步具备了应对新增祝福方式的扩展要求。同时由于其采用的“依赖注入”方式要求李四的业务逻辑控制模块对其所需的 “ISendable”实例进行注入,理论上已经初步具体了“IOC反转控制”的雏形。

    对“IOC反转控制”此时带来的优势就是:确保了“红色框”内的模块是具有应对变化的能力,在后继新增新祝福方式时,UT.MessageService.dll组件可以完全不做任何修改。

 

新的问题

该程序被集成到了三款应用中,这些应用分别采用不同的消息发送方式,于是张三同时维护着三个系统,

其中各自核心代码基本如下:

    UT公司(微信方式)

string message = "新年快乐! 过节费5000.";
ISendable greetTool = new WechatHelper();
GreetMessageService service = new GreetMessageService(greetTool);
service.Greet(message);

    UT编辑部(短信方式) 

string message = "新年快乐! 过节费5000.";
ISendable greetTool = new SMSHelper();
GreetMessageService service = new GreetMessageService(greetTool);
service.Greet(message);

     UT房产(邮件方式)

string message = "新年快乐! 过节费5000.";
ISendable greetTool = new EmailHelper();
GreetMessageService service = new GreetMessageService(greetTool);
service.Greet(message);

本着对工作和客户的认真负责,张三长时间在这些“版本维护”、“产品兼容”等脏活累活中摸爬滚打,心力憔悴……

版本六

 

 

 

 

To IOC,代码结构演变

标签:

原文地址:http://www.cnblogs.com/wj033/p/5783483.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!