1、什么是简单工厂
简单工厂模式简单来说就是创建一个工厂类,通过输入的参数创建对象赋值给基类,完成对想要的派生类的调用,从而达成目标,具体的操作均在子类中完成,工厂类只负责运算逻辑和给基类赋值。该模式有三部分:
工厂类库:实现创建所有实例的选择类型,被外界调用的接口。它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。
抽象类库:所要创建的类的基类,描述类所有实例所共有的公共接口(方法),可以是抽象类也可是接口类型(interface)。
具体类库:所有要创建的具体实例对象。
概述【进一步加深理解】:
首先将需要创建的各种不同产品对象的相关代码封装到不同的类中,这些类称为具体产品类。
而将它们公共的代码进行抽象和提取后封装在一个抽象产品类中,每一个具体产品类都是抽象产品类的子类;
然后提供一个工厂类用于创建各种产品,在工厂类中提供一个创建产品的工厂方法,该方法可以根据所传入的参数的不同创建不同的具体产品对象;
客户端只需要调用工厂类的工厂方法并传入相应的参数即可得到一个产品对象
2、使用
使用简单工厂模式完成客户使用相机的选择
1、接口类库(基类):相机共有功能
namespace Icamreaaa
{
public interface ICamera
{
string Name { get; set; }
void OpenCamera(); //打开相机
void CollectOne(); //采集一张
void ContiuousAcquiation(); //连续采集
void CloseCamera(); //关闭相机
}
}
2、具体类库(继承接口类库,引用接口类库):实现现有相机,巴斯勒、康耐视,以后新加相机只需在此类库新添
namespace CameraModel
{
public class BSL : ICamera
{
public string Name { get; set; }
public BSL()
{
Name = "巴斯勒";
}
public void CloseCamera()
{
MessageBox.Show($"关闭{Name}相机");
}
public void CollectOne()
{
MessageBox.Show($"采集一张{Name}相机图片");
}
public void ContiuousAcquiation()
{
MessageBox.Show($"连续采集{Name}相机图片");
}
public void OpenCamera()
{
MessageBox.Show($"打开{Name}相机");
}
}
}
namespace CameraModel
{
public class KNS : ICamera
{
public string Name { get; set; }
public KNS()
{
Name = "康耐视";
}
public void CloseCamera()
{
MessageBox.Show($"关闭{Name}相机");
}
public void CollectOne()
{
MessageBox.Show($"采集一张{Name}相机图片");
}
public void ContiuousAcquiation()
{
MessageBox.Show($"连续采集{Name}相机图片");
}
public void OpenCamera()
{
MessageBox.Show($"打开{Name}相机");
}
}
}
3、工厂类库:根据参数的不同返回不同类的实例
namespace BLL
{
public class CamreaFaitcy
{
public static ICamera Greatr(string cam)
{
ICamera camera = null; //被创建的实例通常都是基类
switch (cam) //根据参数的不同返回不同类的实例
{
case "巴斯勒":
camera = new BSL();
break;
case "康耐视":
camera = new KNS();
break;
}
}
}
}
调用工厂类库实现不同相机的选择
namespace FormsApp1
{
public partial class Form1 : Form
{
ICamera camera1 = null;
ICamera camera2 = null;
public Form1()
{
InitializeComponent();
camera1 = CamreaFaitcy.Greatr("巴斯勒");
camera2 = CamreaFaitcy.Greatr("康耐视");
}
private void button1_Click(object sender, EventArgs e) //打开相机按钮
{
camera1.OpenCamera();
}
private void button2_Click(object sender, EventArgs e) //采集一张按钮
{
camera1.CollectOne();
}
private void button3_Click(object sender, EventArgs e) //连续采集按钮
{
camera1.ContiuousAcquiation();
}
private void button4_Click(object sender, EventArgs e) //关闭相机按钮
{
camera1.CloseCamera();
}
}
}
当然,这样并不符合客户需求,相机变动还是涉及改动代码
我们利用反射去获取对应的实例
首先在配置文件配置好需要创建对象(实现类)的程序集路径和类名
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
<appSettings>
<add key="Name" value="D:\vs项目\设计模式\简单工厂模式\简单工厂练习-蔡\CameraModel\bin\Debug\CameraModel.dll"/>
<add key="className" value="CameraModel.KNS"/>
</appSettings>
</configuration>
基类和实现类我们不要变,在工厂类里获取App配置文件的值,通过反射获取实例对象
namespace BLL
{
public class CamreaFaitcy
{
public static ICamera Greatr()
{
string Name = ConfigurationManager.AppSettings["Name"];
string className = ConfigurationManager.AppSettings["className"];
//LoadFrom(程序集位置).CreateInstance(命名空间.类名);
return (ICamera)Assembly.LoadFrom(Name).CreateInstance(className);
}
}
}
这样,我们就可以通过修改配置文件相机类的类名来实现打开不同相机