接口隔离原则,反射,特性,依赖注入
接口隔离原则:服务调用者不会多要
违反接口隔离原则情况一:
情景实例:女孩开车老撞车,男朋友想给她买个坦克开,目标:这个女生既能开车也能开坦克
代码再现:
public class Program { static void Main(string[] args) { Driver driver = new Driver(new Car()); driver.Driving(); } } public interface IVehicle { void Run(); } public interface ITank { void Run(); void Fire(); } public class Car : IVehicle { public void Run() { Console.WriteLine("Car is running!"); } } public class Tank : ITank { public void Fire() { Console.WriteLine("I can firing!"); } public void Run() { Console.WriteLine("Tank is running!"); } } public class Driver { private IVehicle vehicle; public Driver(IVehicle vehicle) { this.vehicle = vehicle; } public void Driving() { this.vehicle.Run(); } }
代码可知,这个女孩只能开实现IVechel的交通工具,想让她开坦克,就得添加一个ITank 类型字段,这样做得话,会导致多要了一种功能:坦克的“开火”,简言之这个ITank接口是个胖接口,可做如下优化:
public interface ISweep { void Fire(); } public interface ITank:IVehicle,ISweep { }
这种做法注意千万注意过犹不及,功能分化成太多小接口,会导致颗粒度太小。
违反接口隔离原则情况二:
例:将上述代码中Driver中的是ITank 类型字段,从而将合格的IVechel这个小接口挡在消费之外
例:当应用foreach迭代元素:
static void Main(string[] args) { int[] arr1 = new int[] { 1, 2, 3, 4, 5 }; ArrayList arr2 = new ArrayList { 1, 2, 3, 4, 5 }; var arr3 = new OnlyIEnumble(arr1); Console.WriteLine(Sum(arr1)); Console.WriteLine(Sum(arr2)); //Console.WriteLine(Sum(arr3)); } public static int Sum(ICollection collection) { int result = 0; foreach (var item in collection) { result += (int)item; } return result; }
这样是没有问题的,但当我们实现自己的IEnumerable类之后,ICollection就不能满足需求了
public class Program { static void Main(string[] args) { int[] arr1 = new int[] { 1, 2, 3, 4, 5 }; ArrayList arr2 = new ArrayList { 1, 2, 3, 4, 5 }; var arr3 = new OnlyIEnumble(arr1); Console.WriteLine(Sum(arr1)); Console.WriteLine(Sum(arr2)); //Console.WriteLine(Sum(arr3)); } public static int Sum(ICollection collection) { int result = 0; foreach (var item in collection) { result += (int)item; } return result; } } public class OnlyIEnumble : IEnumerable { private int[] arr_; public OnlyIEnumble(int[] arr) { arr_ = arr; } public IEnumerator GetEnumerator() { return new MyEnum(this); } //成员类 //迭代器 public class MyEnum : IEnumerator { private OnlyIEnumble OnlyIEnumble; private int _head; public MyEnum(OnlyIEnumble onlyIEnumble) { OnlyIEnumble = onlyIEnumble; _head = -1; } public object Current { get { return (object)OnlyIEnumble.arr_[_head]; } } public bool MoveNext() { if (++_head<OnlyIEnumble.arr_.Length) { return true; } return false; } public void Reset() { _head = -1; } } }
接口的显示实现
public class Program { static void Main(string[] args) { var man = new WarmKiller(); man.Love(); Ikill realman =new WarmKiller(); realman.Kill(); } } public interface IWarm { void Love(); } public interface Ikill { void Kill(); } public class WarmKiller : IWarm,Ikill { public void Love() { Console.WriteLine("I love every one for ever"); } void Ikill.Kill() { Console.WriteLine("Let me kill the enemy"); } }
反射
获取该对象的动态描述信息来构造一个实例
依赖注入
public class Program { static void Main(string[] args) { ServiceCollection services = new ServiceCollection(); services.AddScoped(typeof(IVichel), typeof(Car)); services.AddScoped(); var provider= services.BuildServiceProvider(); var driver =(Driver) provider.GetService(typeof(Driver)); driver.Driving(); } } public class Driver { private IVichel _vichel; public Driver(IVichel vichel) { _vichel = vichel; } public void Driving() { _vichel.Run(); } } public interface IVichel { void Run(); } public class Car : IVichel { public void Run() { Console.WriteLine("I running car"); } }