如何在 matlab 包中使用静态工厂方法?
How do I use static factory method in matlab package?
我在 +mypackage\MyClass.m
下有以下 class 定义
classdef MyClass
properties
num
end
methods (Static)
function obj = with_five()
obj = MyClass(5);
end
end
methods
function obj = MyClass(num)
obj.num = num;
end
end
end
我使用 with_five() 作为静态工厂方法。
以下脚本应创建两个对象。
import mypackage.MyClass
class_test1 = MyClass(5);
class_test2 = MyClass.with_five();
class_test1 已创建。
对于 class_test2 它说:
Error using MyClass.with_five
Method 'with_five' is not defined for class 'MyClass' or is removed from MATLAB's search path.
Error in Testpackage (line 4)
class_test2 = MyClass.with_five();
当我将 MyClass.m 放在包文件夹之外并删除“导入”语句时,它起作用了。
我做错了什么?
我认为您缺少的是当您导入静态方法时,您必须导入 class 名称和方法名称 (https://au.mathworks.com/help/matlab/matlab_oop/importing-classes.html)
这个有效:
classdef MyClass
properties
num
end
methods (Static)
function obj = with_five()
obj = MyClass(5);
end
end
methods
function obj = MyClass(num)
obj.num = num;
end
end
end
然后执行以下操作:
>> import MyClass.with_five
>> x = with_five
输出:
x =
MyClass with properties:
num: 5
也就是说:不要在其自身的成员函数中创建对象 class!正如您所建议的,更好的选择是将工厂搬到不同的 class。如果你想制作一堆电锯,你永远不会去尝试设计一个带有按钮的电锯来构建电锯。你宁愿设计一个工厂来生产专门用来砍树的电锯。
一个'static factory'不是坏事。这实际上是一种非常常见的模式,尤其是在 C# 中。但是,工厂永远是自己的class。从另一个继承或扩展 class 的对象调用该方法(我不确定你甚至可以在 Matlab 中做...)如果不是致命的话,肯定会造成混淆。我也想不出你需要这样做的任何理由。事实上我不明白为什么 with_five()
应该是静态的
MATLAB 中有一些关于包和静态方法的古怪东西。
首先,包内的函数必须使用包名称来引用其他函数或同一包内的 classes(参见 here)。所以静态方法mypackage.MyClass.with_five()
必须声明如下:
methods (Static)
function obj = with_five()
obj = mypackage.MyClass(5);
end
end
没有这个,我看到:
>> mypackage.MyClass.with_five
Undefined function or variable 'MyClass'.
Error in mypackage.MyClass.with_five (line 8)
obj = MyClass(5);
其次,在创建 class 的对象之前,不会加载静态 class 方法(至少是包内 classes 的方法)。所以我们需要先调用class构造函数:
>> clear classes
>> mypackage.MyClass.with_five
Undefined variable "mypackage" or class "mypackage.MyClass.with_five".
>> mypackage.MyClass(1);
>> mypackage.MyClass.with_five
ans =
MyClass with properties:
num: 5
如果我们导入 class:
也是如此
>> clear classes
>> import mypackage.MyClass
>> MyClass.with_five
Undefined variable "mypackage" or class "mypackage.MyClass.with_five".
>> MyClass(3);
>> MyClass.with_five
ans =
MyClass with properties:
num: 5
第二点在 R2017a(生成上述输出)中是正确的,但在 R2021a 中不再正确。我不知道这是在哪个 MATLAB 版本中修复的,但在 R2021a 中,不再需要创建 class 的对象来使用其静态方法。
我在 +mypackage\MyClass.m
下有以下 class 定义classdef MyClass
properties
num
end
methods (Static)
function obj = with_five()
obj = MyClass(5);
end
end
methods
function obj = MyClass(num)
obj.num = num;
end
end
end
我使用 with_five() 作为静态工厂方法。
以下脚本应创建两个对象。
import mypackage.MyClass
class_test1 = MyClass(5);
class_test2 = MyClass.with_five();
class_test1 已创建。
对于 class_test2 它说:
Error using MyClass.with_five
Method 'with_five' is not defined for class 'MyClass' or is removed from MATLAB's search path.
Error in Testpackage (line 4)
class_test2 = MyClass.with_five();
当我将 MyClass.m 放在包文件夹之外并删除“导入”语句时,它起作用了。
我做错了什么?
我认为您缺少的是当您导入静态方法时,您必须导入 class 名称和方法名称 (https://au.mathworks.com/help/matlab/matlab_oop/importing-classes.html)
这个有效:
classdef MyClass
properties
num
end
methods (Static)
function obj = with_five()
obj = MyClass(5);
end
end
methods
function obj = MyClass(num)
obj.num = num;
end
end
end
然后执行以下操作:
>> import MyClass.with_five
>> x = with_five
输出:
x =
MyClass with properties:
num: 5
也就是说:不要在其自身的成员函数中创建对象 class!正如您所建议的,更好的选择是将工厂搬到不同的 class。如果你想制作一堆电锯,你永远不会去尝试设计一个带有按钮的电锯来构建电锯。你宁愿设计一个工厂来生产专门用来砍树的电锯。
一个'static factory'不是坏事。这实际上是一种非常常见的模式,尤其是在 C# 中。但是,工厂永远是自己的class。从另一个继承或扩展 class 的对象调用该方法(我不确定你甚至可以在 Matlab 中做...)如果不是致命的话,肯定会造成混淆。我也想不出你需要这样做的任何理由。事实上我不明白为什么 with_five()
应该是静态的
MATLAB 中有一些关于包和静态方法的古怪东西。
首先,包内的函数必须使用包名称来引用其他函数或同一包内的 classes(参见 here)。所以静态方法mypackage.MyClass.with_five()
必须声明如下:
methods (Static)
function obj = with_five()
obj = mypackage.MyClass(5);
end
end
没有这个,我看到:
>> mypackage.MyClass.with_five
Undefined function or variable 'MyClass'.
Error in mypackage.MyClass.with_five (line 8)
obj = MyClass(5);
其次,在创建 class 的对象之前,不会加载静态 class 方法(至少是包内 classes 的方法)。所以我们需要先调用class构造函数:
>> clear classes
>> mypackage.MyClass.with_five
Undefined variable "mypackage" or class "mypackage.MyClass.with_five".
>> mypackage.MyClass(1);
>> mypackage.MyClass.with_five
ans =
MyClass with properties:
num: 5
如果我们导入 class:
也是如此>> clear classes
>> import mypackage.MyClass
>> MyClass.with_five
Undefined variable "mypackage" or class "mypackage.MyClass.with_five".
>> MyClass(3);
>> MyClass.with_five
ans =
MyClass with properties:
num: 5
第二点在 R2017a(生成上述输出)中是正确的,但在 R2021a 中不再正确。我不知道这是在哪个 MATLAB 版本中修复的,但在 R2021a 中,不再需要创建 class 的对象来使用其静态方法。