如何在MATLAB中正确实现工厂模式?

时间:2014-07-01 18:20:22

标签: matlab oop factory

我正在编写一个程序,我可以从可用的Sensor对象列表中进行选择;在选择和用户验证时,程序应该实例化Sensor

以下代码片段是我可能天真地做的事情:

switch userInput
    case 'Sensor A' 
        s = SensorA; % subclass of Sensor

    case 'Sensor B'
        s = SensorB; % subclass of Sensor

    %...
end

这里有一些明显的问题,但我遇到的最大问题是使其具有可扩展性。我希望能够创建许多不同的Sensor子类(或让其他开发人员生成Sensor子类),而无需不断添加到此switch语句。更一般地说,我想坚持open/closed principle。我应该能够拥有许多不同的Sensor子类。 (我还希望使用可用的uicontrol填充弹出菜单Sensors,但如果这个问题得到解决,这可能会得到解决。)其他天真的解决方案,例如偷看到{{1}的文件夹由于每个子类的对象构造可能不同,因此子类也不能很好地工作。

我相信我希望使用factory method pattern,但我并不完全确定如何实施它。我可以将上面的代码段放到单独的Sensor中,但这只会移动SensorFactory语句,这意味着扩展它需要修改它。

如何正确实现工厂方法模式,以便每次添加新的switch子类时工厂对象都不需要修改?

2 个答案:

答案 0 :(得分:4)

关于可扩展性,您可以使用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

这个类可以像这样使用:

在代码的开头创建工厂:

factory = SensorFactory();

在某些初始化部分中,动态添加新传感器:

factory.RegisterSensor('Custom Sensor', @() createCustomSensor());
factory.RegisterSensor('Specific Sensor aperture=42', @() createSpeficSensor(42));
factory.RegisterSensor('Specific Sensor aperture=666', @() createSpecificSensor(666));

注意:出于自动化目的,这也可以解析某些文件夹中的类文件。每个类都有一个静态方法来获取传感器的用户名。这里只是一些想法和伪代码:

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  

然后,在某些GUI部分中,添加一个列出所有可用传感器的组合:

set(myCombo, 'String', factory.GetListOfSensors());

最后,在运行部分中,实例化适当的传感器:

index = get(myCombo, 'Value');

name = factory.GetListOfSensors();
name = name{index};

sensor = factory.CreateSensor(name);

答案 1 :(得分:0)

我真的没有理由在这里使用工厂模式。 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()

使用它,fun可以是返回传感器对象的函数或构造函数的名称或函数句柄。