在面向对象编程时对于类的划分有哪些心得?
程序员文章站
2022-05-31 17:57:52
...
有时候一些东西可以写成一个类也可以多个类,如何兼顾各种约束,找到一个合适的平衡点?
例如Python自有的cgi.escape和HTMLParser.HTMLParser,混入帕斯卡命名法不说,将这两个功能这样封装是出于何种考虑?
其次了解面向对象的原则
前期的需求分析的时候,把需求、功能划分细致一点。然后,把要做的功能分几堆。某一堆功能专注做某一类事情,比如数据库读,数据库写,接口交互,数据计算等。
你看,天然的不就出来“类”这个东西了么。
设计的时候,重点注意两个方面。
第一,接口必须隔离。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(单一功能、开闭原则、里氏替换、接口隔离以及依赖反转) 根据业务吧,
如果从面相对象的思路去思考,
无非是把概念进行封装,
概念可以分为物件,
行为和状态,
当然,
还有一些是自己认为它是一个完整的概念,
也可以划分出去,
单独描绘,
有点像画画。 类要封装变化。把容易根据需求变化的地方封装起来,这也对应设计模式的开闭原则(对派生开放,对修改封闭)
例如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(单一功能、开闭原则、里氏替换、接口隔离以及依赖反转) 根据业务吧,
如果从面相对象的思路去思考,
无非是把概念进行封装,
概念可以分为物件,
行为和状态,
当然,
还有一些是自己认为它是一个完整的概念,
也可以划分出去,
单独描绘,
有点像画画。 类要封装变化。把容易根据需求变化的地方封装起来,这也对应设计模式的开闭原则(对派生开放,对修改封闭)