经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
Matlab原型模式 - sw-lab
来源:cnblogs  作者:sw-lab  时间:2019/5/27 8:52:27  对本文有异议

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

ValueA.m

  1. classdef ValueA
  2. properties
  3. name
  4. end
  5. methods
  6. function obj = ValueA(name)
  7. obj.name = name;
  8. end
  9. end
  10. end

测试代码:

 

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

RefB.m

  1. classdef RefB < handle
  2. properties
  3. name
  4. end
  5. methods
  6. function obj = RefB(name)
  7. obj.name = name;
  8. end
  9. end
  10. end

测试代码:

 

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

  1. classdef(HandleCompatible) BaseV
  2. end

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

RefA.m

  1. classdef RefA < handle
  2. properties
  3. name
  4. refB
  5. end
  6. methods
  7. function obj = RefA()
  8. end
  9. function copyobj = clone(obj)
  10. copyobj = RefA();
  11. copyobj.name = obj.name;
  12. copyobj.refB = obj.refB.clone();
  13. end
  14. end
  15. end

RefB.m

  1. classdef RefB < handle
  2. properties
  3. name
  4. end
  5. methods
  6. function obj = RefB()
  7. end
  8. function copyobj = clone(obj)
  9. copyobj = RefB();
  10. copyobj.name = obj.name;
  11. end
  12. end
  13. end

test1.m

  1. a = RefA();
  2. a.name = 'a-name';
  3. a.refB = RefB();
  4. a.refB.name = 'a-rb-name';
  5. b = a.clone();
  6. b.refB.name = 'b-rb-name';
  7. disp(b.refB.name);
  8. disp(a.refB.name);

结果:

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

RefAA.m

  1. classdef RefAA < handle
  2. properties
  3. name
  4. refBB
  5. end
  6. methods
  7. function obj = RefAA()
  8. end
  9. function copyobj = clone(obj)
  10. copyobj = RefAA();
  11. metaobj = metaclass(obj);
  12. props = {metaobj.PropertyList.Name};
  13. for i = 1:length(props)
  14. prop = obj.(props{i});
  15. if(isa(prop,'handle'))
  16. copyobj.(props{i}) = prop.clone();
  17. else
  18. copyobj.(props{i}) = prop;
  19. end
  20. end
  21. end
  22. end
  23. end

RefBB.m

  1. classdef RefBB < handle
  2. properties
  3. name
  4. end
  5. methods
  6. function obj = RefBB()
  7. end
  8. function copyobj = clone(obj)
  9. copyobj = RefBB();
  10. metaobj = metaclass(obj);
  11. props = {metaobj.PropertyList.Name};
  12. for i = 1:length(props)
  13. prop = obj.(props{i});
  14. if(isa(prop,'handle'))
  15. copyobj.(props{i}) = prop.clone();
  16. else
  17. copyobj.(props{i}) = prop;
  18. end
  19. end
  20. end
  21. end
  22. end

test2.m

  1. a = RefAA();
  2. a.name = 'a-name';
  3. a.refBB = RefBB();
  4. a.refBB.name = 'a-rb-name';
  5. b = a.clone();
  6. b.refBB.name = 'b-rb-name';
  7. disp(b.refBB.name);
  8. disp(a.refBB.name);

运行结果

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

AH.m

  1. classdef AH < matlab.mixin.Copyable
  2. properties
  3. name
  4. bh
  5. end
  6. methods(Access = protected)
  7. function copyobj = copyElement(obj)
  8. copyobj = copyElement@matlab.mixin.Copyable(obj);
  9. metaobj = metaclass(obj);
  10. props = {metaobj.PropertyList.Name};
  11. for i = 1:length(props)
  12. prop = obj.(props{i});
  13. if(isa(prop,'handle'))
  14. copyobj.(props{i}) = copy(prop);
  15. end
  16. end
  17. end
  18. end
  19. end

BH.m

  1. classdef BH < matlab.mixin.Copyable
  2. properties
  3. name
  4. end
  5. end

test3.m

  1. a = AH();
  2. a.name = 'a-name';
  3. a.bh = BH();
  4. a.bh.name = 'a-rb-name';
  5. b = copy(a);
  6. b.bh.name = 'b-rb-name';
  7. disp(b.bh.name);
  8. disp(a.bh.name);

测试结果:

原文链接:http://www.cnblogs.com/usaddew/p/10922206.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号