c#之接口隔离
1.原则
首先不应该强行要求客户端依赖于它们不用的接口;其次是类之间的依赖应该建立在最小的接口上面。简单点说,客户端需要什么功能,就提供什么接口,对于客户端不需要的接口不应该强行要求其依赖;类之间的依赖应该建立在最小的接口上面,这里最小的粒度取决于单一职责原则的划分。
(1)比如一个人能开车和坦克,它只是一个驾驶员,但是坦克还有武器系统,驾驶员是不能够有武器权限的,所以按照接口隔离原则按照下面的方式进行编写
namespace TestClass { class Program { static void Main(string[] args) { var driver = new Driver(new LightTank()); driver.Run(); Console.ReadKey(); } } interface IVehicle { void Run(); } /// <summary> /// 汽车 /// </summary> class Car : IVehicle { public void Run() { Console.WriteLine("Car is running"); } } /// <summary> /// 卡车 /// </summary> class Truck : IVehicle { public void Run() { Console.WriteLine("Truck is running"); } } /// <summary> /// 坦克 /// c#中类或者接口可以继承多接口,但是不能继承多基类。 /// /// </summary> interface IItank:IVehicle,IWeapon { } class LightTank : IItank { public void Fire() { Console.WriteLine("LightTank is firing"); } public void Run() { Console.WriteLine("LightTank is running"); } } class HeavyTank : IItank { public void Fire() { Console.WriteLine("HeavyTank is firing"); } public void Run() { Console.WriteLine("HeavyTank is running"); } } /// <summary> /// 驾驶员类 /// </summary> class Driver { private IVehicle vehicle; public Driver(IVehicle vehicle) { this.vehicle = vehicle; } public void Run() { vehicle.Run(); } } interface IWeapon { void Fire(); } }
(2)显式接口实现
能够把一些隔离出来的接口隐藏起来,直到显式的引用这个接口,才能使用接口中的方法。就比如人有2面性,一面隐藏起来,一面展示给众人。
下面以这个杀手不太冷为例,主角一面是温文尔雅,一面是冷酷无情
namespace TestClass { class Program { static void Main(string[] args) { var warm = new WarmKiller(); warm.Kill(); warm.Love(); Console.ReadKey(); } } interface IGentlement { void Love(); } interface IKiller { void Kill(); } /// <summary> /// 正常的方式实现接口 /// </summary> class WarmKiller : IGentlement, IKiller { public void Kill() { Console.WriteLine("Kill"); } public void Love() { Console.WriteLine("Love"); } } }
看上面的代码是没问题的,但是在设计上是有问题的。因为一个人有两面性,这是不会轻易让人看出来另一面的。在编程的角度讲,如果一个接口不想轻易的让别人调用,就需要使用显式接口。如下:
namespace TestClass { class Program { static void Main(string[] args) { //调用显示接口方法 IKiller killer = new WarmKiller(); //此时killer只会调用kill方法,不会调用love方法 killer.Kill(); var wk = (IGentlement)killer; wk.Love(); Console.ReadKey(); } } interface IGentlement { void Love(); } interface IKiller { void Kill(); } /// <summary> /// 正常的方式实现接口 /// </summary> class WarmKiller : IGentlement, IKiller { void IKiller.Kill() { Console.WriteLine("Kill"); } public void Love() { Console.WriteLine("Love"); } } }
引于:https://www.bilibili.com/video/BV13b411b7Ht?t=1996&p=29
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术