简体   繁体   English

如何在MATLAB中正确实现Factory Pattern?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM