背景
在实际的生产中,会涉及到需要对接多种相似性较高的系统。具体而言就是业务接口是相同的,但是会出现接口的参数不同的情况。这时做一个对接隔离层就显得优势很明显了。这个隔离层的作用就有了两个基本的作用:
1、单一性,保护我们自己的软件系统的标准型。
2、可扩展性,通过隔离层对外实现对接系统的多样性。
使用 Interface 实现多态优势很明显。
- 多态的五大好处
- 可替换性(substitutability):多态对已存在代码具有可替换性。
- 可扩充性(extensibility):多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。
- 接口性(interface-ability):多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。
- 灵活性(flexibility):它在应用中体现了灵活多样的操作,提高了使用效率。
- 简化性(simplicity):多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。
实现思路
定义一个业务接口
IBehavior
通过继承实现接口方法。
/// <summary>动物行为接口</summary>
public interface IBehavior
{
/// <summary>运动</summary>
public string Motion();
/// <summary>叫声</summary>
public string Sound();
}
两个实现类:小苗,小狗
- 小猫类
/// <summary>小猫行为</summary>
public class CatBehavior : IBehavior
{
public string Motion()
{
return "爬树";
}
public string Sound()
{
return "小猫,喵喵";
}
}
- 小狗类
/// <summary>小狗行为</summary>
public class DogBehavior : IBehavior
{
public string Motion()
{
return "游泳";
}
public string Sound()
{
return "小狗,汪汪";
}
}
如何使用不同的实现类,在 .NET Core 中可以使用 依赖注入 的形式调用。但是在低版本的 .NET Framework想要使用 依赖注入 就有些困难了,并且很多项目也并没有使用到,这时引入依赖注入就显得大材小用了。
但是又想要自动的实例化所需对象,一般会想到使用条件判断的形式,根据不同的条件来实例化相应类的对象。这种形式简单直接,缺点也很明显就是可维护性差、可读性也不高。
可以引入设计模式来解决这个困局。
消除条件判断语句
条件判断语句是常规代码中非常的常见,毕竟是基础语法,但也不是非用不可。
这里我们就引入设计模式来消除:
工厂 + 策略
首先我们要创建一个工厂用来制造不同实现类的对象,然后通过策略来调出工厂所对应的实例对象。
在 Java 中有
Map
和HashMap
可以用来当作工厂,但是在 C# 中没有直接的Map
类型。
C# 中我们可以使用
IDictionary
类型
- 首先给工厂定义产品类型,这里使用枚举定义
/// <summary>小动物枚举</summary>
public enum Animal
{
Tom,
Jerry,
Spike
}
- 定义工厂,及可以生产制造的产品
static IDictionary<Animal, IBehavior> drBehavior = new Dictionary<Animal, IBehavior>()
{
{Animal.Tom, new CatBehavior()},
{Animal.Spike, new DogBehavior()}
};
- 给一个出货口,定义调用接口APIs
public static IBehavior GetMethod(Animal animal)
{
IBehavior behavior = default;
drBehavior.TryGetValue(animal, out behavior);
return behavior;
}
至此我们已经消除了对条件判断语句的依赖。
- 看看我们的成果
模拟实现代码
Shared.GetMethod(Animal.Tom).Sound().Dump();
/// <summary>公服</summary>
public class Shared
{
static IDictionary<Animal, IBehavior> drBehavior = new Dictionary<Animal, IBehavior>()
{
{Animal.Tom, new CatBehavior()},
{Animal.Spike, new DogBehavior()}
};
public static IBehavior GetMethod(Animal animal)
{
IBehavior behavior = default;
drBehavior.TryGetValue(animal, out behavior);
return behavior;
}
}
/// <summary>小动物枚举</summary>
public enum Animal
{
Tom,
Jerry,
Spike
}
/// <summary>小猫行为</summary>
public class CatBehavior : IBehavior
{
public string Motion()
{
return "爬树";
}
public string Sound()
{
return "小猫,喵喵";
}
}
/// <summary>小狗行为</summary>
public class DogBehavior : IBehavior
{
public string Motion()
{
return "游泳";
}
public string Sound()
{
return "小狗,汪汪";
}
}
/// <summary>动物行为接口</summary>
public interface IBehavior
{
/// <summary>运动</summary>
public string Motion();
/// <summary>叫声</summary>
public string Sound();
}