开发区域

MATLAB高级软件开发

封装的糖

汉·索罗是个好人。然而,他有时也很不幸。

图片来源:https://flic.kr/p/h8jDb

没错,你应该也知道汉·索罗被关起来了封装被臭名昭著的黑帮“小屋贾巴”用碳酸盐制成。你看,贾巴在太空黑帮学校被教导,为了保持他的系统按设计工作,他需要将他的系统封装在一个坚固的界面后面。通过他丰富的讨债经验,他知道碳酸盐符合要求。然而,不幸的是,贾巴并没有真正理解封装。他只是把他在学校里学到的最好的实践方法直接应用到实践中,而没有掌握其中的原理。这最终导致了他在Sarlacc矿井被一群乌合之众的行善者所击败。

这里的教训是什么?让我们来理解原则封装,不仅仅是战术最佳实践和习语。例如,我记得曾经被教导过,我们总是将属性(或数据成员或字段等)设为私有,然后只通过setter和getter方法对它们进行操作。问“为什么?”会让讨论变得有趣。如果您有一个带有属性的类,并且您希望对使用您的类的任何人都可以公开访问和修改该属性,那么为什么不直接将属性设置为公共呢?

想想看。我发现很多人都没有。

一种想法是,分配setter有助于对属性进行错误检查。这是事实,但并不完整。即使对于不需要任何验证的属性,我们也应该有空锅炉板直通setter和getter。

好吧,那还有别的原因吗?我并不否认在许多语言中都需要这些方法来封装私有数据。然而,对我来说,起作用的原则是这样做遵循封装背后的原则,即信息隐藏.在许多语言中,这些设置器和获取器允许软件将其实现从接口中分离出来。这使得软件能够从当前的实现发展到另一个满足未来我的需求的实现,当然我还不知道(即使我不知道)有人知道).如果我们在c++或Java®等语言中公开字段或属性,则失去了这种灵活性。是的,在我们的接口中,我们可以访问和修改给定的属性,但是当我们将属性直接公开为public时,这也暴露了实现。具体来说,它立即暴露了一些事情:

  1. 属性实际上存储在对象上(甚至是这个对象!)并且在内存中。
  2. 属性在修改时不会(也永远不可能)服从输入验证,并且在访问时永远不会经过预处理。

即使现在没有输入验证,或者属性保存在对象的内存中,添加这些setter和getter对于将来灵活地改变我们的想法也是很重要的。也许将来我们会重构,并希望将属性的所有权委托给另一个对象。也许我们希望在每次访问时都计算结果。如果我们正确地封装了属性,这种更改根本不是问题。

那么,在MATLAB中,我们是否应该将所有属性都设为私有并编写自己的getter和setter访问方法?绝对不是!事实上,与许多其他语言不同,MATLAB中的属性已经封装。例如,查看以下类:

classdefCarbonite属性(SetAccess =私人)HanSolo结束结束

如你所见,HanSolo属性限制修改,但允许访问该属性。这是界面中唯一的东西。请注意,以下不同的实现都仍然忠实于基本接口,而客户端代码从未变得更加明智。界面中是什么什么,封装的是如何

例子:

委派——指派其他人去做这项工作:

classdefCarbonite此实现委托给其他类。属性(Dependent, SetAccess=private结束属性(Access=private) HanSoloAccessor = HanSoloDelegate;结束方法函数solo = get.HanSolo(carbonite) solo = carbonite. hansoloaccessor . hansolo;结束结束结束

计算-不存储任何东西,每次重新计算:

classdefCarbonite这个实现每次都会创建一个新的HanSolo属性(Dependent, SetAccess=private结束方法函数solo = get.HanSolo(carbonite) solo = utils.createNewHanSolo;结束结束结束

预处理——在getter中添加一点味道,在setter中做一些错误检查:

classdefCarbonite此实现对HanSolo的存储值进行预处理他把帽子还了回来,这次他的标志性帽子来自另一套帽子。%的电影。如果属性是可修改的,则可以将setter添加到%修改值时执行错误检查。属性(SetAccess =私人)HanSolo结束属性(Access=private) IndyHat =印第安纳琼斯软呢帽;结束方法函数solo = get.HanSolo(carbonite) solo = carbonite. hansolo;solo.add (carbonite.IndyHat);结束结束结束

好的,你明白了。MATLAB的属性模型不会破坏封装,因此不需要锅炉板setter和getter。可以公开属性集并获得访问权限以匹配是否希望访问或修改它,并且可以在不公开实现细节的情况下执行此操作,因为始终可以添加集。财产得到的。财产方法来更改实现。实现仍然是,跟我说....封装!

那么贾巴的错误是什么呢?他不明白什么是有漏洞的抽象概念。他仍然暴露了他的一些实现,因为他对汉索罗奖感到非常自豪,他把汉索罗作为他最喜欢的装饰展示。贾巴以为自己被封存在碳酸盐里了,他没有利用封装来实现信息隐藏.每个人都知道胶囊里有什么,包括一个新晋的绝地武士和他的朋友们(其中有一个是非常忠诚的伍基人,我可以补充一下)。如果贾巴把他的战利品藏了起来,或者他的碳酸盐再厚一点,这样就没有人能分辨汉·索罗的厚板和其他所有拖欠债务的走私者的区别了,也许他很久以前还活着,在一个遥远的星系里。

...或什么if he used this implementation?

classdefCarbonite%这个实现每次克隆汉索罗作为讨厌的绝地的诱饵。属性(Dependent, SetAccess=private结束属性(访问=私人)RealHanSolo结束方法函数solo = get.HanSolo(carbonite) solo =克隆(carbonite. realhansolo);结束结束结束

这样既能惩罚真正的汉·索罗又能让他的朋友们不再烦他。

总之,我们应该理解封装背后的原理,而不仅仅是公式。我们不要像贾巴那样,他的软件一点都不好。




发布与MATLAB®R2016a

|

评论

如欲留言,请点击在这里登录您的MathWorks帐户或创建一个新帐户。