More Related Content
Similar to 腾讯大讲堂05 面向对象应对之道 (20)
More from George Ang (20)
腾讯大讲堂05 面向对象应对之道
- 13. OO(OO( 或者说语言或者说语言 )) 的核心思想—的核心思想—
表达领域概念表达领域概念
语言的语法都是比较简单的。不过同语言的语法都是比较简单的。不过同
样的语法写出来的代码却有好坏高低样的语法写出来的代码却有好坏高低
之分。之分。
重要的区别就在于重要的区别就在于表达领域概念的水表达领域概念的水
平平
重要的原则就是重要的原则就是 :“:“ 程序(代码)应该程序(代码)应该
反映人的思想,而不是相反。”反映人的思想,而不是相反。” MartinMartin
fowler.fowler. (《分析模式》)(《分析模式》)
- 17. 通过对领域概念应用通过对领域概念应用 OOOO 原则,原则,
分析模式,设计模式等等手段对分析模式,设计模式等等手段对
对象职责进行抽象,细分职责。对象职责进行抽象,细分职责。
形成最终静态对象图。形成最终静态对象图。
通过对用例画时序图,确认对象通过对用例画时序图,确认对象
职责是否可行,恰当。职责是否可行,恰当。
- 22. 释意接口的例子释意接口的例子
int CPlayer::StandUp( int iSessionID )int CPlayer::StandUp( int iSessionID )
{{
int iOpenNum = 0;int iOpenNum = 0;
iOpenNum = m_Sessions.GetLastIdx();iOpenNum = m_Sessions.GetLastIdx();
//// 下面两个判断判断违法情况。下面两个判断判断违法情况。
if( iSessionID < 0if( iSessionID < 0 ))
{{
}}
else if(iSessionID > iOpenNum)else if(iSessionID > iOpenNum)
{{
}}
}}
- 25. 实体表达的例子实体表达的例子
char sNowDate[20]={0};char sNowDate[20]={0};
char sLastDate[20]={0};char sLastDate[20]={0};
GetDate(time(NULL),sNowDate);GetDate(time(NULL),sNowDate);
GetDate(iReserve[LastGive], sLastDate);GetDate(iReserve[LastGive], sLastDate);
if(strcmp(sNowDate, sLastDate) > 0)if(strcmp(sNowDate, sLastDate) > 0)
{{
}}
elseelse
{{
}}
- 26. 同一个功能的另外一种写法 也是实际代码。同一个功能的另外一种写法 也是实际代码。
int CGiveDaily::OnGive(CAttach *pPA, int iHE)int CGiveDaily::OnGive(CAttach *pPA, int iHE)
{{
Date dToday(time(NULL));Date dToday(time(NULL));
Date dLastDay(pPA->GetGiveHELastTime());Date dLastDay(pPA->GetGiveHELastTime());
if(dLastDay == dToday)if(dLastDay == dToday)
{{
}}
elseelse
{{
}}
}}
- 27. 可以看出 抽取出了 日期类,用日期类可以看出 抽取出了 日期类,用日期类
来表达人的思想,而不是只记得使用哪来表达人的思想,而不是只记得使用哪
个个 APIAPI 来实现功能。来实现功能。
日期这个概念在这个需求里面是比较重日期这个概念在这个需求里面是比较重
要的一个概念。面向对象就表达出了这要的一个概念。面向对象就表达出了这
个概念个概念。。
- 29. 实际产品对进房需求的演化实际产品对进房需求的演化
第一个版本第一个版本 :: 限制一下玩家最低,最高积分限制一下玩家最低,最高积分
。。
第二个版本超级玩家和网管要优先进房第二个版本超级玩家和网管要优先进房
第三个版本如果是出租房间需要是承租方第三个版本如果是出租房间需要是承租方
才能进房才能进房
第四个版本如果是比赛房间需要是比赛方第四个版本如果是比赛房间需要是比赛方
才能进房才能进房
第五个版本需要拥有某种道具第五个版本需要拥有某种道具
第六个版本如果是欢乐场房间需要检查欢第六个版本如果是欢乐场房间需要检查欢
乐豆上下限制。乐豆上下限制。
- 37. 隐含概念表达实例隐含概念表达实例
在在 QQGameQQGame 里面对房间模式的描述结构如里面对房间模式的描述结构如
下。不同的房间模式,具有不一样的基本下。不同的房间模式,具有不一样的基本
行为。行为。
我们通过不同的工厂实现来屏蔽掉这一层我们通过不同的工厂实现来屏蔽掉这一层
变化。不同的房间聚合不同的生成工厂。变化。不同的房间聚合不同的生成工厂。
房间模式是挖掘出来的概念,抽象工厂表房间模式是挖掘出来的概念,抽象工厂表
达出了这个概念。达出了这个概念。
- 42. OCP(Open-Closed Principle) :OCP(Open-Closed Principle) : 开放开放 -- 关闭原则关闭原则
对扩展要说对扩展要说 YESYES ,对修改说,对修改说 NONO 。。
LSP(Liskov Substitution Principle) : LSPLSP(Liskov Substitution Principle) : LSP 原则原则
父母要对孩子负责。父母要对孩子负责。
SRP(Single Responsibility Principle) :SRP(Single Responsibility Principle) : 单一职责原单一职责原
则则
感情要单一,不要脚踏两支船。感情要单一,不要脚踏两支船。
DIP(Dependency Inversion Principle) :DIP(Dependency Inversion Principle) : 关系返转原关系返转原
则则
不要一天打不要一天打 1010 个电话给我,有结果我会通知你。个电话给我,有结果我会通知你。
ISP(Interface Segregation Principle) :ISP(Interface Segregation Principle) : 接口隔离原则接口隔离原则
让李部长只负责开发吧,市场就让辛部长做吧让李部长只负责开发吧,市场就让辛部长做吧
- 44. 五项技术原则实例五项技术原则实例 -- 单一职责单一职责
实际代码例子实际代码例子
class CDBCtrlclass CDBCtrl
{{
public:public:
CDBCtrl();CDBCtrl();
~CDBCtrl();~CDBCtrl();
int Initialize(const char *szCfgFile);int Initialize(const char *szCfgFile);
int PrepareToRun();int PrepareToRun();
int Run();int Run();
void* operator new(size_t nSize);void* operator new(size_t nSize);
void operator delete( void* pMem);void operator delete( void* pMem);
static int CountSize();static int CountSize();
static CSharedMem *pCurrentShm;static CSharedMem *pCurrentShm;
private:private:
int ReadCfg(const char *szCfgFile);int ReadCfg(const char *szCfgFile);
int LoadProxyCfgFromFile(char *szProxyFile, int& iProxyNumber);int LoadProxyCfgFromFile(char *szProxyFile, int& iProxyNumber);
int LoadGivenRuleFromFile(char *szRuleFile, int& iRuleCount);int LoadGivenRuleFromFile(char *szRuleFile, int& iRuleCount);
int LoadForbidRuleFromFile(char *szRuleFile, int& iRuleCount);int LoadForbidRuleFromFile(char *szRuleFile, int& iRuleCount);
int ReadPublicCfg(const char *szCfgFile);int ReadPublicCfg(const char *szCfgFile);
int LoadCreditConfig(const char *szCfgFile);int LoadCreditConfig(const char *szCfgFile);
int CheckRunFlags();int CheckRunFlags();
int ConnectToProxys();int ConnectToProxys();
int CheckAndDispatchInputMsg();int CheckAndDispatchInputMsg();
int RoutineCheck();int RoutineCheck();
int DispatchOneCode(short nCodeLength, BYTE* pbyCode);int DispatchOneCode(short nCodeLength, BYTE* pbyCode);
int PostInternalMsgToHandle(int iHandleID, CMsg *pMsg);int PostInternalMsgToHandle(int iHandleID, CMsg *pMsg);
int NofityDBHandles(CMsg *stMsg) ;int NofityDBHandles(CMsg *stMsg) ;
TDBCfg m_stDBCfg;TDBCfg m_stDBCfg;
CTCPConn m_astProxyConn[MAXPROXYNUMBER];CTCPConn m_astProxyConn[MAXPROXYNUMBER];
CDBHandle* m_apHandles[MAXHANDLENUMBER];CDBHandle* m_apHandles[MAXHANDLENUMBER];
- 45. class CMainCtrlclass CMainCtrl
{{
public:public:
CMainCtrl();CMainCtrl();
virtual ~CMainCtrl();virtual ~CMainCtrl();
virtual int Initialize();virtual int Initialize();
virtual int Run();virtual int Run();
int ReloadCfg();int ReloadCfg();
int CheckRunFlag();int CheckRunFlag();
protected:protected:
private:private:
};};
- 47. 五项技术原则实例五项技术原则实例 -- 开闭原则开闭原则
QQGameQQGame 最经典的例子,最经典的例子, Main FrameMain Frame 可以可以
不动代码,游戏服务可以源源不断输出新的不动代码,游戏服务可以源源不断输出新的
游戏。觉得这个是最核心的规则。游戏。觉得这个是最核心的规则。(下图引(下图引
用自用自 zengyuzengyu 《《 QQGameQQGame 服务器架构技服务器架构技
术》)术》)
- 48. 五项技术原则实例五项技术原则实例 -- 依赖倒置依赖倒置
问题界面控件,比如问题界面控件,比如 Button,ListBoxButton,ListBox ,等。,等。
它们都是想做成通用的,也就是说和业务它们都是想做成通用的,也就是说和业务
逻辑不相关。但是事件响应 是通过界面控逻辑不相关。但是事件响应 是通过界面控
件传递到逻辑的。件传递到逻辑的。
问怎么做到界面控件和业务逻辑隔离?问怎么做到界面控件和业务逻辑隔离?
- 51. 实际代码例子:实际代码例子:
class CmdObserverclass CmdObserver
{{
public:public:
CmdObserver();CmdObserver();
virtual ~CmdObserver();virtual ~CmdObserver();
virtual int CmdDone(CCommand *pCmd,int iResult =virtual int CmdDone(CCommand *pCmd,int iResult =
CmdSucceed);CmdSucceed);
};};
class MsgObserverclass MsgObserver
{{
public:public:
MsgObserver(){}MsgObserver(){}
virtual ~MsgObserver(){}virtual ~MsgObserver(){}
virtual int OnMsg(CMsg *pMsg) = 0;virtual int OnMsg(CMsg *pMsg) = 0;
};};
五项技术原则实例五项技术原则实例 -- 接口隔离接口隔离
- 55. 业务层根据业务层根据 Evans DDDEvans DDD ,可以再细分为应,可以再细分为应
用层和领域层两种,在业务层设计编码中用层和领域层两种,在业务层设计编码中
,大量应用,大量应用 OOOO 设计原则和设计模式。设计原则和设计模式。
领域层定义:负责表达业务领域概念、业领域层定义:负责表达业务领域概念、业
务状态以及业务规 则,是整个业务软件核务状态以及业务规 则,是整个业务软件核
心和重点。心和重点。
应用层定义:负责完成功能,并且协调丰应用层定义:负责完成功能,并且协调丰
富的领域对象来实现功能,不能包括业务富的领域对象来实现功能,不能包括业务
规则,无业务状态;规则,无业务状态;
- 56. 从开发每个过程看从开发每个过程看 OOOO 方法论的方法论的
应用应用
1.1. 需求分析,用户活动图,软件需求规格需求分析,用户活动图,软件需求规格
说明书,领域建模。说明书,领域建模。 --OOA--OOA
2.2. 概要设计概要设计 // 详细设计—详细设计— OODOOD 分析和设计分析和设计
的边界很难明确分开。的边界很难明确分开。
3.3. 编码编码 // 测试测试 --OOP--OOP
4.4. 发布发布
5.5. 从从 11 再循环到再循环到 44
- 58. OOAOOA 实例实例
系统需求:考评系统。 某系统需求:考评系统。 某 XXXX 公司要建立公司要建立
一个考评系统。一个考评系统。
大体上领导考虑 要从德智体等几个方面综大体上领导考虑 要从德智体等几个方面综
合考虑。合考虑。
德包括考勤,同事意见,领导意见等;智德包括考勤,同事意见,领导意见等;智
包括技术各项指标,比如操作系统,网络包括技术各项指标,比如操作系统,网络
,领域理解等;体包括体育各项指标,比,领域理解等;体包括体育各项指标,比
如羽毛球,乒乓球等。如羽毛球,乒乓球等。
从这些方面给一个人打分。请用从这些方面给一个人打分。请用 OOOO 描述一描述一
下这个对象系统下这个对象系统 ..
- 62. 设计设计 -OOD-OOD
设计模式介绍 《深入浅出设计模式》 强烈设计模式介绍 《深入浅出设计模式》 强烈
推荐此书。推荐此书。
设计模式某个环境下,对某个设计问题的设计模式某个环境下,对某个设计问题的
一种解决方式的描述。一种解决方式的描述。
设计模式强调设计模式强调把容易变化和不变部分分离把容易变化和不变部分分离。。
让变化部分容易变化。让变化部分容易变化。
在日常开发中,找到变化点,积累变化面在日常开发中,找到变化点,积累变化面
是重要的。是重要的。
- 69. 观察者实际代码例子观察者实际代码例子
class CmdObserverclass CmdObserver
{{
public:public:
CmdObserver();CmdObserver();
virtualvirtual
~CmdObserver();~CmdObserver();
virtual intvirtual int
CmdDone(CCommaCmdDone(CComma
nd *pCmd,int iResultnd *pCmd,int iResult
= CmdSucceed);= CmdSucceed);
};};
class CCommandclass CCommand
{{
public:public:
CCommand();CCommand();
virtual ~CCommand();virtual ~CCommand();
virtual intvirtual int
RegisterObserver(CmdObserverRegisterObserver(CmdObserver
*pObserver);*pObserver);
virtual int NotifyObserver(int iResult =virtual int NotifyObserver(int iResult =
CmdSucceed);CmdSucceed);
private:private:
CSet<CmdObserver*CSet<CmdObserver*
,MAXOBSERVERNUM > m_ObserverSet;,MAXOBSERVERNUM > m_ObserverSet;
};};
这个实例中,命令是属于基础设施层的东西,但是要这个实例中,命令是属于基础设施层的东西,但是要
通知上层业务逻辑,自己的状态变迁。所以使用观察通知上层业务逻辑,自己的状态变迁。所以使用观察
- 77. 设计模式实例设计模式实例 -- 职责链职责链
应用层协议确定分发问题:应用层协议确定分发问题:
比如我们要分析网络上各种应用层协议内比如我们要分析网络上各种应用层协议内
容。包括容。包括 smtp,http,pop3,ftpsmtp,http,pop3,ftp 等等。应用层协等等。应用层协
议是会增加的。现在问题是一个网络连接议是会增加的。现在问题是一个网络连接
,我们无法知道它走的是什么协议。,我们无法知道它走的是什么协议。
一个简单的端口是无法准确判断的。一个简单的端口是无法准确判断的。
问怎么做这个问题的设计方案。问怎么做这个问题的设计方案。
- 83. 设计模式实例—设计模式实例— ReactorReactor
做许多网络服务器做许多网络服务器 // 客户端的时候,基本上客户端的时候,基本上
每一个都会用到每一个都会用到 selectselect 或类似功能函数。多或类似功能函数。多
线程线程 // 多进程模式除外。多进程模式除外。
当当 selectselect 检测到某个检测到某个 fdfd 有数据的时候,我有数据的时候,我
们再去读取数据。基本上这部分代码和我们再去读取数据。基本上这部分代码和我
们的业务逻辑代码混合在一起。们的业务逻辑代码混合在一起。
在一个网络服务器里面,基本都需要定时在一个网络服务器里面,基本都需要定时
器的操作。器的操作。
这些每一个网络服务器都需要的东西,能这些每一个网络服务器都需要的东西,能
否提取出来?形成一个通用解决框架。否提取出来?形成一个通用解决框架。
- 85. 设计模式实例—异步命令模式设计模式实例—异步命令模式
高效的网络服务器高效的网络服务器 // 客户端经常遇到异步操客户端经常遇到异步操
作问题。作问题。
异步响应回来的时候,如何知道异步请求异步响应回来的时候,如何知道异步请求
时候的状态是什么一直是个问题。时候的状态是什么一直是个问题。
这个操作超时,完成,失败和业务逻辑的这个操作超时,完成,失败和业务逻辑的
隔离也存在问题。隔离也存在问题。
ACTACT 异步回调异步回调 TOKENTOKEN 的概念。的概念。
Editor's Notes
- 想表达面向对象的主要观念,方法和原则。
设计模式是方法层面上的东西。
在这些方法之后是面向对象的观念在支撑。
为什么这样做是好的?什么是好的标准?
想结合许多代码的例子来表明面向对象怎么来看这2个问题。
理解了面向对象的观念,对于方法层面的理解应该会更好一点。同时对于全局写代码时可以建立自己的原则。
- 介绍面向对象的一般手法,原则和几个设计模式来。
需要2个小时。
- 这个希望能够能强化。很多毕业生不能够理解一个软件要写三年
很容易把这个搞成一个短期行为。
24小时不停机的海量用户服务
或者上千万,上亿用户使用的软件
产品/策划很难把握3个月/6个月后的产品规划。
持续不断的需求,一般产品3年后还在持续不断开发是常见的情况。
- 第一点
比如要考虑详细的统计信息方便搜集情况和定位问题;
要考虑关键数据的安全策略;
要考虑方便的日志机制定位问题;等等。不在本文档讨论范围。
- 细粒度结构设计关注软件需求,需求分析,关注程序内部结构设计,代码实现。
对于细粒度的开发活动,面向对象有一个体系来支撑。
OO是一个方法论。本文档着力描述它的应对方式。