C#上位机工厂模式
- 在C#中,工厂设计模式(Factory Pattern) 是一种创建型设计模式,核心目的是封装对象的创建过程,将对象的"使用"与"创建"解耦,让客户端无需直接依赖具体类,而是通过"工厂"间接获取对象。这种模式能提高代码的灵活性、可维护性和扩展性,尤其适合需要频繁创建相似类型对象的场景。
- 工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式,而不需要向客户端暴露创建逻辑。在上位机软件开发中,工厂模式特别有用,因为我们需要创建各种硬件设备接口、数据处理器、通信协议等对象。
演示:
cs
interface IProduct { void Op(); }
class ProductA : IProduct { public void Op() => Console.WriteLine("A"); }
class ProductB : IProduct { public void Op() => Console.WriteLine("B"); }
class Factory {
public static IProduct Create(string type) => type switch {
"A" => new ProductA(), "B" => new ProductB(), _ => null
};
}
// 使用
Factory.Create("A")?.Op(); // 输出: A
示列
cs
// 1. 定义产品接口
interface IProduct { void Operation(); }
// 2. 具体产品实现
class ProductA : IProduct {
public void Operation() => Console.WriteLine("产品A");
}
class ProductB : IProduct {
public void Operation() => Console.WriteLine("产品B");
}
// 3. 工厂类
class Factory {
public static IProduct Create(string type) =>
type switch {
"A" => new ProductA(),
"B" => new ProductB(),
_ => throw new ArgumentException("未知类型")
};
}
// 4. 使用
class Program {
static void Main() {
IProduct product = Factory.Create("A");
product.Operation(); // 输出: 产品A
}
}
2. 上位机中的典型应用场景
2.1 设备通信工厂
cs
// 设备通信接口
public interface IDeviceCommunication
{
bool Connect();
bool Disconnect();
byte[] ReadData();
bool WriteData(byte[] data);
}
// 具体设备实现
public class ModbusDevice : IDeviceCommunication
{
public bool Connect()
{
Console.WriteLine("Modbus设备连接...");
return true;
}
public bool Disconnect()
{
Console.WriteLine("Modbus设备断开...");
return true;
}
public byte[] ReadData()
{
// Modbus协议读取数据
return new byte[] { 0x01, 0x03, 0x00, 0x01 };
}
public bool WriteData(byte[] data)
{
Console.WriteLine($"Modbus写入数据: {BitConverter.ToString(data)}");
return true;
}
}
public class SiemensPLCDevice : IDeviceCommunication
{
public bool Connect()
{
Console.WriteLine("西门子PLC连接...");
return true;
}
// ... 其他实现
}
// 设备工厂
public class DeviceFactory
{
public static IDeviceCommunication CreateDevice(DeviceType type)
{
return type switch
{
DeviceType.Modbus => new ModbusDevice(),
DeviceType.SiemensPLC => new SiemensPLCDevice(),
DeviceType.OmronPLC => new OmronPLCDevice(),
DeviceType.MitsubishiPLC => new MitsubishiPLCDevice(),
_ => throw new ArgumentException("不支持的设备类型")
};
}
}
public enum DeviceType
{
Modbus,
SiemensPLC,
OmronPLC,
MitsubishiPLC
}
2.2 数据解析工厂
cs
// 数据解析接口
public interface IDataParser
{
object Parse(byte[] rawData);
string GetDataType();
}
// 工厂方法模式实现
public abstract class DataParserFactory
{
public abstract IDataParser CreateParser();
public object ParseData(byte[] data)
{
var parser = CreateParser();
return parser.Parse(data);
}
}
// 具体工厂
public class TemperatureParserFactory : DataParserFactory
{
public override IDataParser CreateParser()
{
return new TemperatureDataParser();
}
}
public class PressureParserFactory : DataParserFactory
{
public override IDataParser CreateParser()
{
return new PressureDataParser();
}
}
2.3 通信协议工厂(抽象工厂)
cs
// 抽象工厂接口
public interface IProtocolFactory
{
IDataSender CreateDataSender();
IDataReceiver CreateDataReceiver();
IDataValidator CreateDataValidator();
}
// 具体工厂
public class TcpIpProtocolFactory : IProtocolFactory
{
public IDataSender CreateDataSender()
{
return new TcpDataSender();
}
public IDataReceiver CreateDataReceiver()
{
return new TcpDataReceiver();
}
public IDataValidator CreateDataValidator()
{
return new TcpDataValidator();
}
}
public class SerialProtocolFactory : IProtocolFactory
{
public IDataSender CreateDataSender()
{
return new SerialDataSender();
}
public IDataReceiver CreateDataReceiver()
{
return new SerialDataReceiver();
}
public IDataValidator CreateDataValidator()
{
return new SerialDataValidator();
}
}
3. 完整示例:上位机设备管理系统
cs
using System;
using System.Collections.Generic;
namespace FactoryPatternDemo
{
// 设备基类
public interface IDevice
{
string DeviceId { get; }
bool Initialize();
DeviceStatus GetStatus();
byte[] Read();
bool Write(byte[] data);
}
public enum DeviceStatus
{
Disconnected,
Connected,
Error
}
// 具体设备
public class PLCDevice : IDevice
{
public string DeviceId { get; }
public PLCDevice(string id)
{
DeviceId = id;
}
public bool Initialize()
{
Console.WriteLine($"PLC设备 {DeviceId} 初始化...");
return true;
}
public DeviceStatus GetStatus()
{
return DeviceStatus.Connected;
}
public byte[] Read()
{
// 模拟读取PLC数据
return new byte[] { 0x00, 0x01, 0x02, 0x03 };
}
public bool Write(byte[] data)
{
Console.WriteLine($"向PLC {DeviceId} 写入数据");
return true;
}
}
public class SensorDevice : IDevice
{
public string DeviceId { get; }
public SensorDevice(string id)
{
DeviceId = id;
}
public bool Initialize()
{
Console.WriteLine($"传感器设备 {DeviceId} 初始化...");
return true;
}
public DeviceStatus GetStatus()
{
return DeviceStatus.Connected;
}
public byte[] Read()
{
// 模拟传感器数据
Random rand = new Random();
return BitConverter.GetBytes(rand.NextDouble() * 100);
}
public bool Write(byte[] data)
{
Console.WriteLine($"配置传感器 {DeviceId}");
return true;
}
}
public class RobotDevice : IDevice
{
public string DeviceId { get; }
public RobotDevice(string id)
{
DeviceId = id;
}
public bool Initialize()
{
Console.WriteLine($"机器人设备 {DeviceId} 初始化...");
return true;
}
public DeviceStatus GetStatus()
{
return DeviceStatus.Connected;
}
public byte[] Read()
{
// 读取机器人状态
return BitConverter.GetBytes(1); // 状态码
}
public bool Write(byte[] data)
{
Console.WriteLine($"控制机器人 {DeviceId} 动作");
return true;
}
}
// 设备工厂
public static class DeviceFactory
{
public static IDevice CreateDevice(DeviceType type, string deviceId)
{
return type switch
{
DeviceType.PLC => new PLCDevice(deviceId),
DeviceType.Sensor => new SensorDevice(deviceId),
DeviceType.Robot => new RobotDevice(deviceId),
_ => throw new ArgumentException("未知的设备类型")
};
}
// 通过配置创建设备
public static IDevice CreateDeviceFromConfig(DeviceConfig config)
{
IDevice device = CreateDevice(config.Type, config.DeviceId);
if (device.Initialize())
{
Console.WriteLine($"设备 {config.DeviceId} 创建并初始化成功");
return device;
}
throw new Exception($"设备 {config.DeviceId} 初始化失败");
}
}
public enum DeviceType
{
PLC,
Sensor,
Robot
}
public class DeviceConfig
{
public string DeviceId { get; set; }
public DeviceType Type { get; set; }
public string IPAddress { get; set; }
public int Port { get; set; }
public Dictionary<string, string> Parameters { get; set; }
}
// 设备管理器
public class DeviceManager
{
private readonly List<IDevice> _devices = new List<IDevice>();
public void AddDevice(DeviceConfig config)
{
try
{
var device = DeviceFactory.CreateDeviceFromConfig(config);
_devices.Add(device);
}
catch (Exception ex)
{
Console.WriteLine($"添加设备失败: {ex.Message}");
}
}
public void ReadAllDevicesData()
{
foreach (var device in _devices)
{
var data = device.Read();
Console.WriteLine($"设备 {device.DeviceId} 数据: {BitConverter.ToString(data)}");
}
}
public IDevice GetDevice(string deviceId)
{
return _devices.Find(d => d.DeviceId == deviceId);
}
}
class Program
{
static void Main(string[] args)
{
var manager = new DeviceManager();
// 通过工厂创建不同类型的设备
var plcConfig = new DeviceConfig
{
DeviceId = "PLC001",
Type = DeviceType.PLC,
IPAddress = "192.168.1.100",
Port = 502
};
var sensorConfig = new DeviceConfig
{
DeviceId = "SENSOR001",
Type = DeviceType.Sensor,
Parameters = new Dictionary<string, string>
{
{ "SamplingRate", "100" },
{ "Range", "0-100" }
}
};
var robotConfig = new DeviceConfig
{
DeviceId = "ROBOT001",
Type = DeviceType.Robot,
IPAddress = "192.168.1.101",
Port = 3000
};
manager.AddDevice(plcConfig);
manager.AddDevice(sensorConfig);
manager.AddDevice(robotConfig);
// 读取所有设备数据
manager.ReadAllDevicesData();
// 控制特定设备
var robot = manager.GetDevice("ROBOT001");
robot?.Write(new byte[] { 0x01, 0x02 });
}
}
}
4. 上位机中工厂模式的最佳实践
4.1 结合依赖注入
cs
public interface IDeviceService
{
IDevice CreateDevice(string deviceType);
}
public class DeviceService : IDeviceService
{
private readonly IServiceProvider _serviceProvider;
public DeviceService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public IDevice CreateDevice(string deviceType)
{
return deviceType switch
{
"PLC" => _serviceProvider.GetService<PLCDevice>(),
"Sensor" => _serviceProvider.GetService<SensorDevice>(),
_ => throw new ArgumentException("不支持的设备类型")
};
}
}
4.2 配置文件驱动
cs
<!-- Devices.config -->
<Devices>
<Device Type="Modbus"
Class="FactoryPatternDemo.ModbusDevice"
Assembly="FactoryPatternDemo.dll"/>
<Device Type="Siemens"
Class="FactoryPatternDemo.SiemensPLCDevice"
Assembly="FactoryPatternDemo.dll"/>
</Devices>
cs
public class ConfigurableDeviceFactory
{
private readonly Dictionary<string, Type> _deviceTypes = new();
public ConfigurableDeviceFactory(string configPath)
{
LoadDeviceConfig(configPath);
}
public IDevice CreateDevice(string typeName, params object[] args)
{
if (_deviceTypes.TryGetValue(typeName, out Type deviceType))
{
return (IDevice)Activator.CreateInstance(deviceType, args);
}
throw new ArgumentException($"未注册的设备类型: {typeName}");
}
private void LoadDeviceConfig(string configPath)
{
// 从XML或JSON加载配置
_deviceTypes["Modbus"] = typeof(ModbusDevice);
_deviceTypes["Siemens"] = typeof(SiemensPLCDevice);
// ...
}
}
5. 工厂模式的优缺点
优点:
-
松耦合:客户端与具体产品类解耦
-
易于扩展:添加新产品只需添加新工厂类
-
集中管理:对象创建逻辑集中在一处
-
符合开闭原则:对扩展开放,对修改关闭
缺点:
-
类数量增加:每个产品对应一个工厂类
-
增加了系统复杂性
-
需要额外的抽象层