日历

September 2020
M T W T F S S
 123456
78910111213
14151617181920
21222324252627
282930  

成员方法的疑问

Home Forums 《冒号课堂》讨论区 成员方法的疑问

  • This topic is empty.
Viewing 2 reply threads
  • Author
    Posts
    • #1055
      Todd
      Member

      OOP是以数据为中心组织算法的。OOP把面向过程的函数变成了类的成员方法的过程,也是过程抽象到数据抽象的转变过程。但我发现,即使在OOP中过程抽象似乎还有存在的意义,特别是,我常对成员方法的设计还是有感觉拿不准的地方。比如:

      1.STL中的算法多是作为函数提供的,没有作为容器类的成员方法。对于这个问题,我觉得STL的设计有它的合理的一面:因为sort,transform等算法本身也是一种被人所熟知的概念,它的独立存在是对概念的直接表达;独立性也增强了算法的普适性。但这样的设计也有缺点:对象的行为不够饱满;用户不仅需要获取对象,还需要依赖额外的算法,没有达到数据抽象的高内聚效果。了解mixin以后,我觉得也许mixin是解决这个问题的更好方法:既保持算法的独立性;又可以方便地混入对象达到数据对算法的吸附作用。

      2.对于存在交互情况,比如:画笔在画纸上作画,我觉得不管是paper.draw(pen)还是pen.draw(paper)都不如用函数表达为draw(paper,pen)来得自然。据我所知,这种情况在建模中常抽象为一种服务来表达某一功能,比如:DrawService。

      请问有没有一个比较好的方法来分析算法什么情况下适合设计为类的成员方法呢?什么情况下又应该作为独立的函数(C++)或者是抽象为服务呢?

    • #1198
      hui
      Keymaster

      >>1.STL中的算法多是作为函数提供的,没有作为容器类的成员方法。

      在STL中,有意将算法与容器分离,让iterator作为它们之间的桥梁。这可令算法不受容器的限制,从而尽可能地普适。至于说到没有达到高内聚的效果,那是不可避免的,在一定层次上的(关注点分离带来的)解耦与(数据与运算粘合带来的)内聚本来就是一对矛盾。

      >>2.对于存在交互情况,比如:画笔在画纸上作画,我觉得不管是paper.draw(pen)还是pen.draw(paper)都不如用函数表达为draw(paper,pen)来得自然。

      这个问题在书中p429也曾简单提到过。如果是两个或两个以上的对象平等合作地完成一项任务,无论谁作为主体对象都不是很合适。引入一个中间的服务对象是一种方法,另外,由于C++支持自由函数,直接用无对象(但最好有namespace)的函数也不失为一种选择。

      >>请问有没有一个比较好的方法来分析算法什么情况下适合设计为类的成员方法呢?什么情况下又应该作为独立的函数(C++)或者是抽象为服务呢?

      你的帖子的题目是“成员方法的疑问”。如果单从设计的角度说,成员方法通常与算法不是一个层面的概念。因为从数据抽象的观点来看,成员方法的API规范中通常是不涉及具体算法的,即只说明what to do,不涉及how to do。当然也有例外,比如成员方法是某种算法的名称。我想你关心的应该是这种情况吧?对于这种情况,我的看法如下:

      1、如果把算法绑定到某个类会影响算法的普适性,则用独立函数比较合适;

      2、如果算法涉及到两个以上的没有明显主次之分的类,则用独立函数或中间服务类比较合适;

      3、其他情况,建议设计为类的成员方法。尤其是如果算法有side-effect,或者需要多个步骤(如各种加密文件的算法),用对象来储存不同的状态比较方便,还能在一定程度上保证调用的次序(比如采用一些辅助的私有变量)。

    • #1199
      Todd
      Member

      >>比如成员方法是某种算法的名称。我想你关心的应该是这种情况吧?

      正是这种情况,谢谢!

Viewing 2 reply threads
  • You must be logged in to reply to this topic.
 请您评分1星(很差)2星(不行)3星(一般)4星(不错)5星(很棒)