Dan*_*hoa 3 oop matlab factory
我正在编写一个程序,可以在其中从可用对象列表中进行选择Sensor;在选择和用户验证后,程序应实例化该Sensor.
下面的代码片段是我可能会天真地做的事情:
switch userInput
case 'Sensor A'
s = SensorA; % subclass of Sensor
case 'Sensor B'
s = SensorB; % subclass of Sensor
%...
end
Run Code Online (Sandbox Code Playgroud)
这里有一些明显的问题,但我遇到的最大问题是使其可扩展。我希望能够创建许多不同的Sensor子类(或让其他开发人员生成Sensor子类),而不必不断添加到此switch语句中。更一般地说,我想坚持开放/封闭原则。我应该能够有很多不同的Sensor子类。(我也想用uicontrol可用的内容填充弹出菜单Sensors,但是如果这个问题得到普遍解决,这可能会得到解决。)其他简单的解决方案,例如查看充满Sensor子类的文件夹也不能很好地工作,因为对象构造可能是每个子类都不同。
我相信我正在寻找使用工厂方法模式,但我不完全确定如何实现它。我可以将上面的代码片段放入一个单独的 中SensorFactory,但这只是移动了switch语句,这意味着扩展它需要修改它。
如何正确实现工厂方法模式,以便每次添加新子类时不需要修改工厂对象Sensor?
关于可扩展性,您可以使用containers.Map对象作为工厂中的哈希表。这是一些简单的例子:
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
Run Code Online (Sandbox Code Playgroud)
这个类可以这样使用:
在代码的开头创建工厂:
factory = SensorFactory();
Run Code Online (Sandbox Code Playgroud)
在某些初始化部分中动态添加新传感器:
factory.RegisterSensor('Custom Sensor', @() createCustomSensor());
factory.RegisterSensor('Specific Sensor aperture=42', @() createSpeficSensor(42));
factory.RegisterSensor('Specific Sensor aperture=666', @() createSpecificSensor(666));
Run Code Online (Sandbox Code Playgroud)
注意:出于自动化目的,这也可以在解析某些文件夹中的类文件时完成。每个类都有一个静态方法来获取传感器的用户名。这里只是一些想法和伪代码:
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
Run Code Online (Sandbox Code Playgroud)
然后,在某些 GUI 部分中,添加一个组合,列出迄今为止所有可用的传感器:
set(myCombo, 'String', factory.GetListOfSensors());
Run Code Online (Sandbox Code Playgroud)
最后,在运行部分,实例化适当的传感器:
index = get(myCombo, 'Value');
name = factory.GetListOfSensors();
name = name{index};
sensor = factory.CreateSensor(name);
Run Code Online (Sandbox Code Playgroud)