简单工厂
情景介绍
有3个动物。猫(Cat)、狗(Dog)、羊(Sheep),他们都有相同的行为吃(Eat)
第一种方案
项目工程如下,分别创建了3个对应的类文件,并且实现他们的Eat方法
Cat.cs
public class Cat
{
public void Eat()
{
Console.WriteLine("猫吃鱼");
}
}
Dog.cs
public class Dog
{
public void Eat()
{
Console.WriteLine("狗吃shi");
}
}
Sheep.cs
public class Sheep
{
public void Eat()
{
Console.WriteLine("羊吃草");
}
}
下面的方式进行调用
Program.cs
class Program
{
static void Main(string[] args)
{
Cat cat = new Cat();
Dog dog = new Dog();
Sheep sheep = new Sheep();
cat.Eat();
dog.Eat();
sheep.Eat();
Console.ReadKey();
}
}
打印输出:
这样,我们就能实现相应的需求了
第二种方案
在上述方案中进行优化
这些动物都具有形同的方法Eat,定义一个接口,先将构建对象等号左边的统一化
项目工程:
添加一个工程,用于定义接口,然后添加一个接口文件IBehavior.cs,用于定于统一的接口。
SimpleFactory工程引用SimpleFactory.Interface.dll
IBehavior.cs
public interface IBehavior
{
void Eat();
}
接下来Cat、Dog、Sheep这3个类分别实现这个接口
Cat.cs
public class Cat : IBehavior
{
public void Eat()
{
Console.WriteLine("猫吃鱼");
}
}
Dog.cs
public class Dog : IBehavior
{
public void Eat()
{
Console.WriteLine("狗吃shi");
}
}
Sheep.cs
public class Sheep : IBehavior
{
public void Eat()
{
Console.WriteLine("羊吃草");
}
}
下面的方式进行调用
Program.cs
class Program
{
static void Main(string[] args)
{
IBehavior cat = new Cat();
IBehavior dog = new Dog();
IBehavior sheep = new Sheep();
cat.Eat();
dog.Eat();
sheep.Eat();
Console.ReadKey();
}
}
使用接口后,通过接口来进行统一化,输出的结果相同
终极方案
为了将对象的创建进行统一的管理,进行如下优化,将对象的创建放置到一个工厂类文件中进行管理
项目工程:
添加了一个工厂文件Factory.cs,代码如下:
public class Factory
{
public static IBehavior CreateInstance(Animal animal)
{
switch (animal)
{
case Animal.Cat:
return new Cat();
case Animal.Dog:
return new Dog();
case Animal.Sheep:
return new Sheep();
default:
throw new Exception("no found");
}
}
}
public enum Animal
{
Cat = 1,
Dog = 2,
Sheep = 3
}
设置一个Animal枚举,提供给调用端使用,来明确创建的对象
调用:
class Program
{
static void Main(string[] args)
{
IBehavior cat = Factory.CreateInstance(Animal.Cat);
IBehavior dog = Factory.CreateInstance(Animal.Dog);
IBehavior sheep = Factory.CreateInstance(Animal.Sheep);
cat.Eat();
dog.Eat();
sheep.Eat();
Console.ReadKey();
}
}
通过上述的优化之后,统一了接口,使用工厂统一管理创建的对象
上述的演变过程就是简单工厂模式
拓展
拓展一
该方法是添加一个配置文件,在配置文件中定义好要创建哪种对象。
在工厂类Factory.cs中添加一个方法,用于读取配置文件,根据配置文件的信息创建对应的对象并返回
项目工程:
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="animal" value="Cat"/>
</appSettings>
</configuration>
Factory.cs文件中添加的方法
private static readonly string AnimalStr = ConfigurationManager.AppSettings["animal"];
public static IBehavior CreateInstanceConfig()
{
Animal animalEnum = (Animal)Enum.Parse(typeof(Animal), AnimalStr);
switch (animalEnum)
{
case Animal.Cat:
return new Cat();
case Animal.Dog:
return new Dog();
case Animal.Sheep:
return new Sheep();
default:
throw new Exception("no found");
}
}
这样我们就可以通过修改配置文件的方式来动态更改需要创建的对象
拓展二
使用反射的方式,在配置文件中设置对应类对象的全路径,通过反射的方式创建对应的对象。
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="animal" value="Cat"/>
<add key="animalReflect" value="SimpleFactory,SimpleFactory.Dog"/>
</appSettings>
</configuration>
Factory.cs文件中添加的方法
private static readonly string AnimalStrRef = ConfigurationManager.AppSettings["animalReflect"];
public static IBehavior CreateInstanceReflect()
{
string assemblyName = AnimalStrRef.Split(',')[0];
string typeName = AnimalStrRef.Split(',')[1];
return (IBehavior)(Activator.CreateInstance(assemblyName,typeName).Unwrap());
}