深入浅出面向对象分析与设计——学习笔记之二

        对昨天问题的解答,有点出乎意料,却又是自己之前实际项目中尝试过类似思路的一种方法。那就是像vdb或质控软件一样,把属性封装到Map中应对所有实体之间的差异,在这过程中,还有以下几点小收获:

        1.概念中的抽象类,并不一定要映射到类中也是不变的抽象类,只要这样做对程序来说更灵活,更易于扩展,换言之,追求面向对象并非最好。(比如乐器Instrument类,也可以设计为普通类,而用其中一个Type字段指明乐器的类型)。

        2.当子类之间的区别只要于属性,而不在于行为时(行为的简单差别可以通过父类中对Map的操作得到实现),可考虑这样:将属性放置在一个Map中,就如数据校验质控软件和vdb中的记录一样,都抽象成DataObject,它们具体属性有什么不同,都放在Map中。这样就不需要根据不同的表来生成不同的类了!而一般的系统,一般都针对每一张表,创建一个实体类:如Person,Order,Book等等。不过,如果子类之间的行为有差别,而必须要在不同子类中定义不同行为的话,就必须要采用多态了。

        3.看看改变软件有多容易,有判断它是否设计良好的最佳方式之一。

        4.内聚性是指:具有内聚性的类关于处理好单一事情,但不会试着做其它事。每一个类的功能都是定义良好的,每一个都是具有高度内聚性的类,这使得它容易变更,不需要涉及其它类的改变。如果一个类做的事情过多并且关联性不大,这就是低内聚,是应该杜绝的。高内聚其实也就表示低耦合。每个类专注自己的事情,并且接口定义良好时,那么它的改变便不需要涉及到其它类的改变。当然,高内聚也并不等同于软件容易变更,有时候设计需要大幅度的变化,从一种情况的高内聚,改变为另一种情况的高内聚。不过低内聚却绝对代表软件很难变更。

        5.解决一个大问题(做一个大的系统)的步骤:

  • 聆听客户,找出他们要你构建什么。
  • 用客户理解的语言组合功能列表(如类比其它类似系统)。
  • 确认你的功能是客户真正想要的。
  • 运用用例图(以及用例)创建系统的蓝图。
  • 将大系统分解成许多较小的部分。
  • 将设计模式运用到系统中较小的部分。
  • 运用基本的OOA&D原则为每一个较小的部分设计程序。

        6.架构是定义好系统最主要的各个模块及各个模块之间的通信,可以写一些主要的类,对于模块内部详细实现,暂时先忽略。在架构某一模块时,应专注于处理模块内部的主要问题及与其它模块的通信,其它模块的内部代码可完全不考虑,以免考虑太多,不知从何下手。模块主要功能及其与其它模块的通信可通过场景的方式来逐步理清。

        7. 面向对象设计原则:

  • 开闭原则:对修改关闭,对扩展开放。就是说写代码时,努力保证自己所写代码能够很好完成工作。努力保证需要修改的话,不要改源码,而是扩展它(具体有继承与组合两种方式)。这在程序变大时,尤其重要,因为修改某些源码会导致程序出问题。
  • 不自我重复原则:通过将共同之处(方法,代码或属性等)抽取出来,并置于单一的地方避免重复的程序代码。没有重复代码除了避免冗余,也使得一个功能需求只在一个地方实现,代码简洁,便于维护与修改。不自我重复原则让系统每一个信息与行为的片段都保存在单一、合理的地方。
  • 单一职责原则:系统里的每一个对象应该具有单一职责,所有对象的服务都应该聚焦在实现该职责上,做到高内聚。单一职责原则并不一定让类变小,相反有时变大,因为一个职责可能是比较大的职责,仅由此职责用到的类,应设为内部类等。
  • Liskov替换原则:子类型必须能够替换其基类型,如果用子类替换基类会把事情弄糟,则说明继承应用有错误。如3DBoard(棋盘)不能继承自Board(棋盘),因为对2D棋盘的操作,应用到3D棋盘时会出问题(即父类引用对子类对象操作会出问题,不应使用多态),而应该采用组合的方式重用。可用一组Board组成3DBoard。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值