[英]How do I correctly implement the Factory Pattern in MATLAB?
I am writing a program in which I can select from a list of available Sensor
objects; 我正在编写一个程序,从中可以从可用的
Sensor
对象列表中进行选择。 upon selection and user validation, the program should instantiate that Sensor
. 在选择和用户验证后,程序应实例化该
Sensor
。
The following code snippet is what I might naively do: 以下代码段是我可能天真地做的:
switch userInput
case 'Sensor A'
s = SensorA; % subclass of Sensor
case 'Sensor B'
s = SensorB; % subclass of Sensor
%...
end
There are some obvious problems here, but the biggest problem I have is making this extensible. 这里有一些明显的问题,但是我最大的问题是使它具有可扩展性。 I want to be able to create lots of various
Sensor
subclasses (or have other developers generate Sensor
subclasses) without having to continuously add to this switch
statement. 我希望能够创建很多各种
Sensor
子类(或让其他开发人员生成Sensor
子类),而不必不断添加到此switch
语句中。 More generally, I want to adhere to the open/closed principle . 更笼统地说,我想遵守开放/封闭原则 。 I ought to be able to have lots of different
Sensor
subclasses. 我应该能够拥有许多不同的
Sensor
子类。 (I also want to populate a popupmenu uicontrol
with the available Sensors
, but that probably gets solved if this problem gets solved generally.) Other naive solutions such as peeking into a folder full of Sensor
subclasses doesn't work very well either, since object construction may be different for each subclass. (我也想用可用的
Sensors
填充popupmenu uicontrol
,但是如果通常解决此问题,则可能会得到解决。)其他幼稚的解决方案,例如窥视充满Sensor
子类的文件夹,也不能很好地工作,因为对象每个子类的构造可能不同。
I believe I'm looking to use the factory method pattern , but I'm not entirely sure how to implement it. 我相信我正在寻找使用工厂方法模式 ,但是我不确定如何实现它。 I could put the above code snippet into a separate
SensorFactory
, but this just moves the switch
statement around, meaning extending it requires modifying it. 我可以将上面的代码片段放入一个单独的
SensorFactory
,但这只会移动switch
语句,这意味着要对其进行扩展需要对其进行修改。
How do I implement the factory method pattern correctly such that the factory object doesn't require modification every time I add a new Sensor
subclass? 如何正确实现工厂方法模式,以使每次添加新的
Sensor
子类时都不需要修改工厂对象?
Regarding extensibility you can use a containers.Map object as a hash table in your factory. 关于可扩展性,您可以在工厂中使用container.Map对象作为哈希表。 Here is some simple example:
这是一些简单的例子:
classdef SensorFactory < handle
% Lifetime
methods
function [factory] = SensorFactory()
% Creates the factory
% Call super class
factory = factory@handle();
% Pre-register some well-known sensors if you want
factory.RegisterSensor('Sensor A', @() error('TODO: Here of course use appropriate method to create sensor A'));
factory.RegisterSensor('Sensor B', @() error('TODO: Here of course use appropriate method to create sensor B'));
factory.RegisterSensor('Sensor C', @() error('TODO: Here of course use appropriate method to create sensor C'));
end
end
methods
function [] = RegisterSensor(factory, sensorName, createSensorCallback)
% Adds new sensor to the factory
factory.dictionnary(sensorName) = createSensorCallback;
end
function [sensorList] = GetListOfSensors(factory)
% Obtains the list of available sensors
sensorList = factory.dictionnary.keys;
end
function [sensor] = CreateSensor(factory, sensorName)
% Creates sensor instance
createCallback = factory.dictionnary(sensorName);
sensor = createCallback();
end
end
properties(GetAccess = private)
dictionnary = containers.Map(); % Hash table
end
end
This class can be used like this: 该类可以这样使用:
At the beginning of the code create the factory: 在代码的开头创建工厂:
factory = SensorFactory();
In some initialization part add new sensors on the fly: 在一些初始化部分中,动态添加新传感器:
factory.RegisterSensor('Custom Sensor', @() createCustomSensor());
factory.RegisterSensor('Specific Sensor aperture=42', @() createSpeficSensor(42));
factory.RegisterSensor('Specific Sensor aperture=666', @() createSpecificSensor(666));
NB: For automation purpose, this may be done also parsing class files in some folder. 注意:出于自动化目的,也可以在某些文件夹中解析类文件来完成此操作。 Each class having a static method to get the user name of the sensor.
每个类都有一个静态方法来获取传感器的用户名。 Just some thoughts and pseudo code here:
这里只是一些想法和伪代码:
classdef MySuperSensor
methods(Static)
funcion [name] = GetUserName()
name = 'My super sensor';
end
end
end
---
l = dir('.\sensors');
foreach file in l
try
meta = eval(sprintf('?%s', l.name));
factory.Register(...GetUserName()..., ...CreateCallback...)
catch
end
end
Then, in some GUI part, add a combo listing all available sensors to date: 然后,在某些GUI部分中,添加一个组合,列出迄今为止所有可用的传感器:
set(myCombo, 'String', factory.GetListOfSensors());
Finally, in the run part, instantiate appropriate sensor: 最后,在运行部分中,实例化适当的传感器:
index = get(myCombo, 'Value');
name = factory.GetListOfSensors();
name = name{index};
sensor = factory.CreateSensor(name);
I don't really see a reason to use the factory pattern here. 我真的看不出在这里使用工厂模式的原因。 A typical piece of code for matlab is:
matlab的典型代码是:
if ischar(fun)
if exist(fun,'function')
fun=str2func(fun)
else
error('invalid input')
end
end
if ~isa(fun, 'function_handle')
error('invalid input')
end
sensor=fun()
Using this, fun can be name or function handle to a function or constructor which returns your sensor object. 使用此功能,fun可以是返回传感器对象的函数或构造函数的名称或函数句柄。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.