有时候一些东西可以写成一个类也可以多个类,如何兼顾各种约束,找到一个合适的平衡点?例如python自有的cgi.escape和htmlparser.htmlparser,混入帕斯卡命名法不说,将这两个功能这样封装是出于何种考虑?回复内容:
以容易写unittest又绝对不会破坏封装为准
首先是方法学:基于用例分析(use case analysis)的方法基于crc方法(class responsibility collaborator)其次了解面向对象的原则抽象原则遵循高内聚,低耦合的原则遵循solid 原则特别是开闭原则(open/closed principle)和单一责任原则(single responsibility principle)最后,持续进行重构
经验之谈。前期的需求分析的时候,把需求、功能划分细致一点。然后,把要做的功能分几堆。某一堆功能专注做某一类事情,比如数据库读,数据库写,接口交互,数据计算等。你看,天然的不就出来“类”这个东西了么。设计的时候,重点注意两个方面。第一,接口必须隔离。solid里提到了单一职责、接口隔离两个原则。单一职责确实很难,有时候打破它的性价比更高。但接口隔离一定要做到。接口不隔离,就不可能单一职责,就很难遵守开闭、里氏等原则。第二,考虑开闭原则。开闭原则是一切软件设计的核心思想。但是要严格做到真的太难了。首先没人能在刚开始的时候就考虑到所有以后可能的变化;其次即使考虑到了,实现起来的成本也会居高不下。所以,在可以接受的工作量范围内,以你和业务、需求方的经验来做一些开闭的设计就行。开发的时候,主要靠经验和技巧来做一些重构。这里可以提一点,就是有些看起来很无聊的代码规范有时候真的很有帮助。比如一个方法不能超过30行,一个类不能超过300行这种。当行数超过规范的时候,你自然就会想重构、拆分子类。另外 @vczh 说到了以unittest为准,这也是一个很好的思路,尤其是在tdd实践中。
如果针对实体的话,按照面向对象对类的定义,一组相同特性的对象可以归一个类就算一个类,如果多个类共用一组属性的,将共用属性组归为一个继承类,然后具体类继承为子类再实现差异。如果能全部归一类又可以分多类,应该没处理好公共属性。
这个问题必须要分开讨论。对于需求变化不频繁的,当然是以test是否方便为依据。至于需求变化频繁的,相信我,只要能跑就行。所以我从来都是尽可能不干业务逻辑层的活,我向来是努力写核心功能。举例来说,对于典型的后端mvc的项目,我一般主要写m,顶多写一点m和c之间的接口。但是c和v的主要部分我一点都不想动。这个时候,我写完我的接口就可以好好以test为依据写类了。
纯靠感觉…
this is why we need design patterns. you may want to refer to gof(“design patterns: elements of reusable object-oriented software”).=============================好吧我没啥写大型项目的经验,还是看以上各位答主答的吧。
solid(单一功能、开闭原则、里氏替换、接口隔离以及依赖反转)
根据业务吧,如果从面相对象的思路去思考,无非是把概念进行封装,概念可以分为物件,行为和状态,当然,还有一些是自己认为它是一个完整的概念,也可以划分出去,单独描绘,有点像画画。
类要封装变化。把容易根据需求变化的地方封装起来,这也对应设计模式的开闭原则(对派生开放,对修改封闭)