博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式——控制反转&依赖注入
阅读量:6841 次
发布时间:2019-06-26

本文共 4607 字,大约阅读时间需要 15 分钟。

一、控制反转:

从简单的代码示例入手:

///     /// 邮件服务类    ///     public class EmailService    {        public string SendMessage()        {            return "发送通知邮件";        }    }    ///     /// 邮件通知类    ///     public class NotifycationSystem    {        private EmailService service;        public NotifycationSystem()        {            service = new EmailService(); //邮件通知类必须精确的知道创建和使用了哪种类型的服务,此处高耦合了。        }        public string InterestingEventHappened()        {            return service.SendMessage();        }    }
共两个类,一个邮件服务类,一个邮件通知类,邮件通知类依赖于邮件服务类。邮件通知类必须精确的知道创建和使用了哪种类型的服务,此处高耦合了。

改进一:在两代码块中引入抽象层,提取接口。

///     /// 邮件服务接口    ///     public interface IMessageService    {        string SendMessage();    }    ///     /// 邮件服务类    ///     public class EmailService : IMessageService    {        public string SendMessage()        {            return "发送通知邮件";        }    }    ///     /// 邮件通知类    ///     public class NotifycationSystem    {        private IMessageService service;//邮件通知类保存服务实现的接口        public NotifycationSystem()        {            service = new EmailService();         }        public string InterestingEventHappened()        {            return service.SendMessage();        }    }
上面将依赖具体实现改为了依赖接口,减少了部分耦合。但是邮件服务类还是在邮件通知类内实例化的,也就是说邮件通知类还是要完全知道邮件服务类的具体细节。

改进二:将选择抽象实现的责任移到服务消费者类的外部。

///     /// 第二层抽象: 服务定位器    ///     public interface IServiceLocator    {        IMessageService GetMessageService();    }    ///     /// 第一层抽象:邮件服务接口    ///     public interface IMessageService    {        string SendMessage();    }    ///     /// 邮件服务类    ///     public class EmailService : IMessageService    {        public string SendMessage()        {            return "发送通知邮件";        }    }    ///     /// 邮件通知类    ///     public class NotifycationSystem    {        private IMessageService service;//邮件通知类保存服务实现的接口。        public NotifycationSystem(IServiceLocator locator)        {            service = locator.GetMessageService();//实现依赖关系被转移到类外。        }        public string InterestingEventHappened()        {            return service.SendMessage();        }    }
扩展一:弱类型服务定位器。

///     /// 第二层抽象: 服务定位器    ///     public interface IServiceLocator    {        object GetService(Type serviceType);    }    ///     /// 第一层抽象:邮件服务接口    ///     public interface IMessageService    {        string SendMessage();    }    ///     /// 邮件服务类    ///     public class EmailService : IMessageService    {        public string SendMessage()        {            return "发送通知邮件";        }    }    ///     /// 邮件通知类    ///     public class NotifycationSystem    {        private IMessageService service;//邮件通知类保存服务实现的接口。        public NotifycationSystem(IServiceLocator locator)        {            service = (IMessageService)locator.GetService(typeof(IMessageService));//实现依赖关系被转移到类外。        }        public string InterestingEventHappened()        {            return service.SendMessage();        }    }

弱类型服务定位器使得这种模式更加灵活,因为他允许请求任意类型的服务类型。采用Type类型的参数,并返回一个非类型化的示例,也就是一个object类型对象。

扩展二:泛型方法。

///     /// 第二层抽象: 服务定位器    ///     public interface IServiceLocator    {        T GetService
();//泛型接口 object GetService(Type serviceType); } ///
/// 第一层抽象:邮件服务接口 /// public interface IMessageService { string SendMessage(); } ///
/// 邮件服务类 /// public class EmailService : IMessageService { public string SendMessage() { return "发送通知邮件"; } } ///
/// 邮件通知类 /// public class NotifycationSystem { private IMessageService service;//邮件通知类保存服务实现的接口。 public NotifycationSystem(IServiceLocator locator) { service = locator.GetService
();//实现依赖关系被转移到类外。 } public string InterestingEventHappened() { return service.SendMessage(); } }
泛型方法,让依赖反转代码看上去更加高效优雅。

二、依赖注入:

1.构造函数注入:

///     /// 邮件通知类    ///     public class NotifycationSystem    {        private IMessageService _service;        public NotifycationSystem(IMessageService service)//构造函数注入        {            _service = service;        }        public string InterestingEventHappened()        {            return _service.SendMessage();        }    }
2.属性注入:

///     /// 邮件通知类    ///     public class NotifycationSystem    {        private IMessageService MessageService { get; set; }        public string InterestingEventHappened()        {            if (MessageService == null)            {                throw new InvalidOperationException("服务类型为赋值!");            }            return MessageService.SendMessage();        }    }

转载地址:http://cazul.baihongyu.com/

你可能感兴趣的文章
LINUX REDHAT第二单元练习题
查看>>
internet protocal ---IP
查看>>
rrdtool生成图像
查看>>
mysql批量写入数据时,注意事项
查看>>
mongodb用户权限配置
查看>>
get提交时中文传值乱码的有关问题
查看>>
mysql存储过程的事务简单学习
查看>>
文件包含漏洞总结
查看>>
vim着色
查看>>
[Python]学习基础篇:字符串的处理
查看>>
CentOS用户及用户组管理
查看>>
yum安装mysql 5.6
查看>>
ubuntu、Centos、win2003开启snmp服务
查看>>
big endian与little endian
查看>>
单机服务器已经安装好二进制mysql5.6.20,然后开启mysql多实例
查看>>
Sys和system用户、sysdba 和sysoper系统权限、dba角色
查看>>
loadrunner的atof函数有问题,请大家慎用!!!
查看>>
[InnoDB系列] - InnoDB独立/共享表空间的转换
查看>>
【STM32 .Net MF开发板学习-24】激光防盗模型
查看>>
OpenGL编程轻松入门(二)
查看>>