欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Matlab原型模式

程序员文章站 2022-12-01 16:18:04
原型(Prototype)模式的定义如下:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。Matlab面向对象编程有两种类,一种是Value Class,一种是Handle Class,Value对象深拷贝的直接通过赋值语句即可实现(实际上是Lazy Copy), ......

原型(prototype)模式的定义如下:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。matlab面向对象编程有两种类,一种是value class,一种是handle class,value对象深拷贝的直接通过赋值语句即可实现(实际上是lazy copy),如下所示:

valuea.m

classdef valuea
    properties
       name
    end    
    methods
        function obj = valuea(name)
            obj.name = name;
        end 
    end
end

测试代码:

Matlab原型模式

 

handle类是引用类,相当于java的引用变量,变量指向具体的地址,handle对象的赋值操作实际上只是浅拷贝,没有拷贝对象的实际数据。如下图所示:

refb.m

classdef refb < handle
    properties
        name
    end
    methods
        function obj = refb(name)
           obj.name = name;          
        end
    end
end

测试代码:

Matlab原型模式

 

注:一个类如果同时继承value类和handle类时,需要在value基类加上关键词handlecompatible,如下所示,其继承后的类仍然是value类。

classdef(handlecompatible) basev
end

出了项目的实际需要,需要对handle类进行深拷贝,可以仿照java的原型模式在handle类中加入clone方法:

refa.m

classdef refa < handle
    properties
        name
        refb
    end
    methods
        function obj = refa()
        end
        function copyobj = clone(obj)
            copyobj = refa();
            copyobj.name = obj.name;
            copyobj.refb = obj.refb.clone();
        end
    end
end

refb.m

classdef refb < handle
    properties
        name
    end
    methods
        function obj = refb()            
        end
        function copyobj = clone(obj)
            copyobj = refb();
            copyobj.name = obj.name;
        end
    end
end

test1.m

a = refa();
a.name = 'a-name';
a.refb = refb();
a.refb.name = 'a-rb-name';
b = a.clone();
b.refb.name = 'b-rb-name';
disp(b.refb.name);
disp(a.refb.name);

结果:

Matlab原型模式

如果要克隆多个属性,可以借助meta.class来实现:

refaa.m

classdef refaa < handle
    properties
        name
        refbb
    end
    methods
        function obj = refaa()
        end
        function copyobj = clone(obj)
            copyobj = refaa();
            metaobj = metaclass(obj);
            props = {metaobj.propertylist.name};
            for i = 1:length(props)
                prop = obj.(props{i});
                if(isa(prop,'handle'))
                    copyobj.(props{i}) = prop.clone();
                else
                    copyobj.(props{i}) = prop;
                end
            end
        end
    end
end

refbb.m

classdef refbb < handle
    properties
        name
    end
    methods
        function obj = refbb()            
        end
        function copyobj = clone(obj)
            copyobj = refbb();
            metaobj = metaclass(obj);
            props = {metaobj.propertylist.name};
            for i = 1:length(props)
                prop = obj.(props{i});
                if(isa(prop,'handle'))
                    copyobj.(props{i}) = prop.clone();
                else
                    copyobj.(props{i}) = prop;
                end
            end
        end
    end
end

test2.m

a = refaa();
a.name = 'a-name';
a.refbb = refbb();
a.refbb.name = 'a-rb-name';
b = a.clone();
b.refbb.name = 'b-rb-name';
disp(b.refbb.name);
disp(a.refbb.name);

运行结果

Matlab原型模式

另外在matlab r2011a开始,可以使用matlab.mixin.copyable自动克隆一个对象,可以利用copy函数来实现对象的克隆。这类似于java的cloneable类。不过不能对属性做递归的深拷贝,如果要实现深拷贝,需要重写copyelement方法,代码如下:

ah.m

classdef ah < matlab.mixin.copyable
    properties
        name
        bh
    end
    methods(access = protected)
        function copyobj = copyelement(obj)
           copyobj = copyelement@matlab.mixin.copyable(obj);
           metaobj = metaclass(obj);
            props = {metaobj.propertylist.name};
            for i = 1:length(props)
                prop = obj.(props{i});
                if(isa(prop,'handle'))
                    copyobj.(props{i}) = copy(prop);
                end
            end
        end
    end
end

bh.m

classdef bh < matlab.mixin.copyable
    properties
        name
    end
end

test3.m

a = ah();
a.name = 'a-name';
a.bh = bh();
a.bh.name = 'a-rb-name';
b = copy(a);
b.bh.name = 'b-rb-name';
disp(b.bh.name);
disp(a.bh.name);

测试结果:

Matlab原型模式