设计6大原则和控制反转(IoC),依赖注入(DI)

1.单一职责原则(Single Responsibility Principle, SRP):

动物类就只需要实现和动物相关的信息,不可用来实现物品的信息
一个类只负责一个功能领域中的相应职责,

2.开闭原则(Open-Closed Principle, OCP):

1.参数尽量以包装的方式传递,2.实体和接口尽量不要修改,3.以扩展的形式进行程序修改和实现
一个软件实体应当对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。

3.里氏代换原则(Liskov Substitution Principle, LSP):

使用子类替换基类/父类不会出现错误和异常,反之则不可
所有引用基类(父类)的地方必须能透明地使用其子类的对象
里氏代换原则告诉我们,在软件中将一个基类对象替换成它的子类对象,程序将不会产生任何错误和异常,反过来则不成立,如果一个软件实体使用的是一个子类对象的话,那么它不一定能够使用基类对象

4.接口隔离原则(Interface Segregation Principle, ISP):

接口尽可能的细小,独立,专一/专门

使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。

5.迪米特法则(Law of Demeter, LoD):

不要和“陌生人”说话、只与你的直接朋友通信等
一个软件实体应当尽可能少地与其他实体发生相互作用。

6.依赖倒置:

通过接口或基类的方式调用方法
依赖倒置原则是五大原则之一:
1.上层模块不应该依赖于下层模块,它们共同依赖于一个抽象.
2.抽象不能依赖于具象,具象依赖于抽象.
什么是上层?使用者就是上层,上例中,Test 类就是上层.
什么是下层?被使用者就是下层.上例中,Test 类使用了 MyDependency 类, MyDependency 类就是下层.
上层不应该依赖下层,Test 类不应该依赖 MyDependency 类,因为如果 MyDependency 类变化了,就是把这种变化所造成的影响传递到上层 Test 类.
因此,上例按照依赖倒置原则修改如下:

   public class Test
    {
        private IDepenency md = new MyDependency();

        public void Print()
        {
            md.Print();
        }
    } 
    public interface IDepenency
    {
        void Print();
    }
    public class MyDependency : IDepenency
    {
        public void Print()
        {
            Console.WriteLine("this is mydependency");
        }
    }

控制反转(IoC):Inversion of Control

(将对象以参数的形式传递给使用的类,通过接口类型调用)
控制反转是一种思想,所谓"控制反转",就是反转获得依赖对象的过程.或许,叫"反转控制"更容易理解.
上例虽然遵循了"依赖倒置原则",但是违背"开放封闭原则",因为如果有一天想修改 md 为 YourDependency 类的实例,则需要修改 Test 类.因此,我们需要反转这种创建对象的过程.

    internal class Program
    {
        private static void Main(string[] args)
        {
            Test test = new Test(new MyDependency());
            test.Print();           
            Console.ReadKey();
        }
    }
    public class Test
    {
        private IDepenency md;

        public Test(IDepenency depenency)
        {
            md = depenency;
        }
        public void Print()
        {
            md.Print();
        }
    }    

上例中,将 md 的创建过程"反转"给了调用者.

依赖注入(DI):Dependency Inject

(通过配置的思路,将类动态的获取,然后以参数的方式传入)
依赖注入设计模式是一种在类及其依赖对象之间实现控制反转(IOC)思想的技术.
所谓依赖注入,就是由IoC容器在运行期间,动态地将某种依赖关系注入到对象之中。
我们先创建一个简易的IoC容器(当然,实际的 IoC 容器复杂得多.):

    public class IoCContainer
    {
        private Dictionary<Type, Object> dic;

        public IoCContainer()
        {
            Init();
        }

        private void Init()
        {
            dic = new Dictionary<Type, object>
            {
                {typeof(IDepenency),new MyDependency() }
            };
        }

        public T GetInstance<T>()
        {
            return (T)dic[typeof(T)];
        }
    }

那么,上例的调用,则可以修改成:

    internal class Program
    {
        private static void Main(string[] args)
        {
            IoCContainer container = new IoCContainer();//创建一个容器
            IDepenency dependency = container.GetInstance<IDepenency>();//获取注册的实例
            Test test = new Test(dependency);
            test.Print();
            Console.ReadKey();
        }
    }

依赖注入分为3中:构造函数注入,属性注入,方法注入,上例属于构造函数注入.
ASP.NET Core 中的依赖注入
ASP.NET Core 内置的IoC容器,只支持构造函数注入,注入的方式如下:
在 Startup 类的 ConfigureServices 方法中注册.

        public void ConfigureServices(IServiceCollection services)
        {            
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            //DI
            services.AddTransient<IDependency, MyDependency>();
        }

使用:

    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        private readonly IDepenency _dependency;
        public ValuesController(IDepenency dependency)
        {
            _dependency = dependency;
        }
        
        ...other codes
  }

参考文章 (返回主页 Matrix海 子)设计模式之六大原则(转载)
(NET未来之路)ASP.NET Core 2.2 基础知识(一) 依赖注入

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章