背景

在实际的生产中,会涉及到需要对接多种相似性较高的系统。具体而言就是业务接口是相同的,但是会出现接口的参数不同的情况。这时做一个对接隔离层就显得优势很明显了。这个隔离层的作用就有了两个基本的作用:
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 中有 MapHashMap 可以用来当作工厂,但是在 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;
}

至此我们已经消除了对条件判断语句的依赖。

  • 看看我们的成果

【C#】接口实现多态增强版_简单工厂模式

模拟实现代码

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();
}