关于继承和组合的一点总结

  入行时一直用c++写端游的逻辑,对这两者的区别几乎是0。

  最先意识到有不同是在看了设计模式之后,但也没啥自己想法,代码照旧,只是依稀有个印象:都说组合好,少用继承。

  用c++的那段时间对这句经验是没多少感受的。后来用erlang、lua、go开始自己设计搭建基础框架,这才在编码层级感受到两者的巨大不同。

  一个印象非常深的例子:上个手游项目MOBA大改造,首先要做个类似dota的开房间系统,5v5。

  想想房间也就是个小号地图嘛,便着手把嵌在活动中的地图代码扣了出来。做成单独的功能类,LogicMap、LogicRoom。谁要就自己去new个新的,暴露的接口也只几个,FindByID、Enter、Exit、Foreach...

  LogicRoom稍微有点不同,放弃了roomID的概念,把它当成了内部的管理变量,所有对外接口都以playerID做索引,甚至放弃了房主的概念,因为它对LogicRoom的功能而言是不必要的,丢给逻辑层自己维护(这个当时纯粹是为了让代码整洁好看而已~囧,后面赚大发了,老大分了一个房主掉线自动切换的单子,给了三小时,五分钟写完<( ̄3 ̄)>)。

  扣完之后意外的发现逻辑层代码颜值提高不少,只需关心什么时候进去、什么时候出来,要通告就随便找个人Foreach下……爽的一比。

  随即回忆起写c++活动的情景,我们的地图系统(对,不能称之为模块了,太轻量~)有严格的继承体系(我那会可不会这么称呼它),然后你写逻辑时随便一扯就扯到它老子cMap那去了,看着糊你一脸的switch...case/if...else,还有几十百八个函数,果断不想理。

  问题是我们大多需要的仅仅只是进出、找人、通知这样的简单功能而已呀。

  继承带来了统一的接口,可以批量处理,可以脚本化,但同时也带来了臃肿、冗余,强迫你照顾本不需要的其它旧逻辑。

  继承归一化的好处,比之于代码可读性的降低,已经不是显现的好处了。反正每次写逻辑的时候,那些基础功能的条理总是要过一遍的,还得费劲看看父类是不是这样(ˇ?ˇ)

  

  想来最初的cMap肯定是精小的,被各种功能地图继承后,添加管理代码,慢慢从颜值九分降到两分儿。

  其中最重要的动机:仅仅为了获得类的功能而去继承它。

  PS:或许还有一点——设计定位缺失。缺乏一个纯粹的数据操作类,单纯的地图数据、相关业务逻辑、消息响应这些是不同层级的东西,全放在一起了。

  组合呢?

  组合最大的好处就是:它能把功能“比较好追踪的”封在一个集合里面。只在一个跟其它的没关。

  这点继承根本做不到。总不免关心基类是不是背着干了什么事。一旦要关心基类逻辑,就得啃其它模块代码。

  前段时间读陈硕的书,他有两句棒极的话:面向对象和基于对象,是两种不同的编程方式;虚函数只是编译器给你的便捷函数指针数组而已。

  后一句有装逼之嫌,但很有道理,他也这么用的。尤其喜欢“基于对象”的说法。

  现在用go,一个语法层面就抛弃了继承的东东,全都是基于对象的组合,清晰度高了许多(当然也有烦人的地方,到处可见的g_server、g_handle )(>﹏<)。

  

  写完看了遍,感觉没什么干货,/(ㄒoㄒ)/~~

  吃根冰棍睡觉了=_=~

  PS:异形版设计模式那一套,借助继承封装、加控制层级,来硬对需求变动的搞法,非大神总是会被搞的。

  PPS:代码写的简单易读改起来也耗不了多少功夫,都能写出简洁代码了,改复杂些还不容易嘛O(∩_∩)O哈!

时间: 2024-11-15 17:58:45

关于继承和组合的一点总结的相关文章

Objective-C基础1:OC中类的继承和组合

1.类的定义和声明 OC中的类声明是以@interface开始@end结束. OC中的类定义以@implementation开始@end结束. OC中的方法声明: - (void) setName : (NSString*) strName;前面的短线-表示这是一个方法,(void)表示返回值, setName表示方法名称,(NSString*) StrName表示参数是NSString*类型,名称是strName,注意:()一定要加 OC中的成员变量定义在类声明的{}中,这一点跟方法声明不一样

[Think In Java]基础拾遗1 - 对象初始化、垃圾回收器、继承、组合、代理、接口、抽象类

目录 第一章 对象导论第二章 一切都是对象第三章 操作符第四章 控制执行流程第五章 初始化与清理第六章 访问权限控制第七章 复用类第九章 接口 第一章 对象导论 1. 对象的数据位于何处? 有两种方式在内存中存放对象: (1)为了追求最大的执行速度,对象的存储空间和生命周期可以在编写程序时确定,这可以通过将对象置于堆栈或者静态存储区域内来实现.这种方式牺牲了灵活性. (2)在被称为堆的内存池中动态地创建对象.在这种方式,知道运行时才知道对象需要多少对象,它们的生命周期如何,以及它们的具体类型.

菜鸟译文(一)——Java中的继承和组合

阅读英文的能力对于程序员来说,是很重要的.这几年也一直在学习英文,今天心血来潮,就在网上找了一篇简短的博文翻译一下.水平一般,能力有限,还请各位看官多多指点. 译文: 本文将会举例说明Java中继承和组合的概念.首先举一个继承的例子,然后展示一下如何用组合来改善继承的设计.最后概括一下如何在它们之间做出选择. 1. 继承 假设我们有一个Insect类.这个类包含两个方法:一个是move(),一个是attack(). class Insect { private int size; private

新秀翻译(一个)——Java在继承和组合

阅读英文的程序猿的能力,这是非常重要的.过去的几年中一直在学习英语,今天心血来潮,在网上找什么鲍文简要翻译. 普通级,能力有限,看官还请大家多多指点. 译文: 本文将会举例说明Java中继承和组合的概念.首先举一个继承的样例.然后展示一下怎样用组合来改善继承的设计.最后概括一下怎样在它们之间做出选择. 1. 继承 假设我们有一个Insect类.这个类包括两个方法:一个是move().一个是attack(). class Insect { private int size; private Str

继承和组合、抽象类和接口

继承和组合的使用原则: 1.很多资料中提到的一点,如果两个类之间是is-a的关系,那么就使用继承,而如果是has-a的关系就使用组合. 但是这也不是代表is-a是使用继承的绝对理由,有时候为了消除继承关系带来的耦合,使用组合可以更好的实现封装细节. 如果在一个系统中大量应用继承,继承层次深了,那么会给系统的开发和维护带来困难. 2.无论何时,如果你使用继承,但是又不想向上转型,那么这个时候就应该慎重选择,只要有可能,就应该考虑使用组合来达 到自己的目的.因为组合在类的运行期间通过类的属性来改变类

java的继承和组合

继承和组合是java中非常常用的两种创建新类型的方法,两者都能提高代码的复用率. 继承主要是想让子类继承父类的基本特性:组合技术通常用于想在新类中使用现有类的功能,而非它的接口.两者的分别是"IS A"和"HAS A"的关系 继承: class Shape { public void draw() { System.out.println("draw a shape"); } public void erase() { System.out.pr

OC学习笔记 面向对象 继承与组合

一.基本概念 程序的世界和人类的“对象”世界在思想上是没有设么区别的,富二代继承了父母,自然就拥有了父母拥有的所有资源,子类继承了父类同样就拥有了父类所有的方法和属性(成员变量). 在这里动物是猫类和狗类的父类,黑猫和白猫类是猫类的子类. 继承的好处: (1)抽取出了重复的代码 (2)建立了类和类之间的联系 继承的缺点: 耦合性太强 二.OC中的继承 @interface Animal:NSObject //动物里继承了NSObject,获得NSObject类的方法: @end @interfa

Java中的继承与组合

本文主要说明Java中继承与组合的概念,以及它们之间的联系与区别.首先文章会给出一小段代码示例,用于展示到底什么是继承.然后演示如何通过“组合”来改进这种继承的设计机制.最后总结这两者的应用场景,即到底应该选择继承还是组合. 1.继承 假设我们有一个名为Insect(昆虫)的类,这个类包含两个方法:1)移动move(): 2)攻击attack(). 代码如下: class Insect { private int size; private String color; public Insect

Java中的继承与组合(转载)

本文主要说明Java中继承与组合的概念,以及它们之间的联系与区别.首先文章会给出一小段代码示例,用于展示到底什么是继承.然后演示如何通过“组合”来改进这种继承的设计机制.最后总结这两者的应用场景,即到底应该选择继承还是组合. 1.继承 假设我们有一个名为Insect(昆虫)的类,这个类包含两个方法:1)移动move(): 2)攻击attack().代码如下: class Insect { private int size; private String color; public Insect(