腾讯大讲堂05 面向对象应对之道

1,399 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,399
On SlideShare
0
From Embeds
0
Number of Embeds
303
Actions
Shares
0
Downloads
27
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • 想表达面向对象的主要观念,方法和原则。
    设计模式是方法层面上的东西。
    在这些方法之后是面向对象的观念在支撑。
    为什么这样做是好的?什么是好的标准?
    想结合许多代码的例子来表明面向对象怎么来看这2个问题。
    理解了面向对象的观念,对于方法层面的理解应该会更好一点。同时对于全局写代码时可以建立自己的原则。
  • 介绍面向对象的一般手法,原则和几个设计模式来。
    需要2个小时。
  • 这个希望能够能强化。很多毕业生不能够理解一个软件要写三年
    很容易把这个搞成一个短期行为。
    24小时不停机的海量用户服务
    或者上千万,上亿用户使用的软件
    产品/策划很难把握3个月/6个月后的产品规划。
    持续不断的需求,一般产品3年后还在持续不断开发是常见的情况。
  • 第一点
    比如要考虑详细的统计信息方便搜集情况和定位问题;
    要考虑关键数据的安全策略;
    要考虑方便的日志机制定位问题;等等。不在本文档讨论范围。
  • 细粒度结构设计关注软件需求,需求分析,关注程序内部结构设计,代码实现。
    对于细粒度的开发活动,面向对象有一个体系来支撑。
    OO是一个方法论。本文档着力描述它的应对方式。
  • 腾讯大讲堂05 面向对象应对之道

    1. 1. 面向对象开发面向对象开发 课程开发课程开发 :penghao:penghao 2008-04-012008-04-01
    2. 2. 课程目的课程目的  描述面向对象编描述面向对象编 程的一般性的手程的一般性的手 法,原则 和技法,原则 和技 巧巧  工欲善其事工欲善其事 ,, 必必 先利其器。先利其器。
    3. 3. 课程大纲课程大纲  引言引言  面向对象的面向对象的表达方法表达方法  面向对象的面向对象的五个原则五个原则  面向对象的面向对象的几个设计模式几个设计模式
    4. 4. 我们面对的是什么?我们面对的是什么?
    5. 5. 这种情况下的应对之道这种情况下的应对之道  规模大且服务不断的情况下对应的非功能规模大且服务不断的情况下对应的非功能 性需求就会要求比较多性需求就会要求比较多 ..  变化多且持续变化的情况下要求程序具有变化多且持续变化的情况下要求程序具有 良好的结构。本文档所关注的核心。良好的结构。本文档所关注的核心。
    6. 6. 程序,服务具有良好结构有两个程序,服务具有良好结构有两个 层面的考虑层面的考虑  大粒度的结构设计。关注的层面比较宏观。大粒度的结构设计。关注的层面比较宏观。 这一块的知识参考 《面向模式的体系结这一块的知识参考 《面向模式的体系结 构》 卷一。本文档不关注。构》 卷一。本文档不关注。
    7. 7. 细粒度结构设计细粒度结构设计 -- 本文档关注的本文档关注的 核心核心
    8. 8. 什么代码写得好?什么叫坏的代什么代码写得好?什么叫坏的代 码?有标准吗?码?有标准吗? 2-52-5
    9. 9. 坏代码举例坏代码举例  僵化:很难对系统进行改动,因为每个改动都会僵化:很难对系统进行改动,因为每个改动都会 迫使许多对系统其他部分的改动。迫使许多对系统其他部分的改动。  脆弱:对系统的改动会导致系统综合改动的地方脆弱:对系统的改动会导致系统综合改动的地方 在概念上无关的许多地方出现问题。在概念上无关的许多地方出现问题。  牢固:很难解开系统的纠结,使之成为一些可重牢固:很难解开系统的纠结,使之成为一些可重 用的组件。用的组件。  粘滞:做正确的事情比做错误的事情要困难。粘滞:做正确的事情比做错误的事情要困难。  不必要的复杂:设计中包含不具有任何直接好处不必要的复杂:设计中包含不具有任何直接好处 的基础结构。的基础结构。  不必要的重复:不必要的重复:  晦涩:很难阅读,理解。晦涩:很难阅读,理解。  (引用于《敏捷软件开发:原则,模式与实践》(引用于《敏捷软件开发:原则,模式与实践》 强烈推荐该书。)强烈推荐该书。)
    10. 10. 好代码的近似标准介绍好代码的近似标准介绍  OOOO (或者说语言)的核心思想(或者说语言)的核心思想  OOOO 的五大技术原则(标准)的五大技术原则(标准)  从从 OOOO 看合理的分层架构看合理的分层架构
    11. 11. OO(OO( 或者说语言或者说语言 )) 的核心思想—的核心思想— 表达领域概念表达领域概念  语言的语法都是比较简单的。不过同语言的语法都是比较简单的。不过同 样的语法写出来的代码却有好坏高低样的语法写出来的代码却有好坏高低 之分。之分。  重要的区别就在于重要的区别就在于表达领域概念的水表达领域概念的水 平平  重要的原则就是重要的原则就是 :“:“ 程序(代码)应该程序(代码)应该 反映人的思想,而不是相反。”反映人的思想,而不是相反。” MartinMartin fowler.fowler. (《分析模式》)(《分析模式》)
    12. 12. 如何来表达一个如何来表达一个 mmog-mmog- 静态视图静态视图 ??
    13. 13. 针对某个领域对象粗分操作,行针对某个领域对象粗分操作,行 为,职责。为,职责。
    14. 14.  通过对领域概念应用通过对领域概念应用 OOOO 原则,原则, 分析模式,设计模式等等手段对分析模式,设计模式等等手段对 对象职责进行抽象,细分职责。对象职责进行抽象,细分职责。 形成最终静态对象图。形成最终静态对象图。  通过对用例画时序图,确认对象通过对用例画时序图,确认对象 职责是否可行,恰当。职责是否可行,恰当。
    15. 15. 实际实际 mmogAImmogAI 表达的例子表达的例子
    16. 16. 表达概念的几种类型表达概念的几种类型  释意接口。释意接口。  表达实体对象表达实体对象  表达约束表达约束  表达流程表达流程 (( 服务服务 ))  表达规格表达规格  隐含机制表达隐含机制表达
    17. 17.  ““ 在初学面向对象时对它们并不熟悉。每学在初学面向对象时对它们并不熟悉。每学 会一个这样的表达的类型,我的设计水平会一个这样的表达的类型,我的设计水平 就又进了一步” “就又进了一步” “ My designs became sharperMy designs became sharper with each one of these I leaned.”with each one of these I leaned.”  Eric EvansEric Evans 《领域驱动设计》强烈推荐该书《领域驱动设计》强烈推荐该书
    18. 18. 释意接口的例子释意接口的例子  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) {{ }}  }}
    19. 19. 推荐写法如下:推荐写法如下:  RoomSessionRoomSession 提取成一个提取成一个对象(类),对象(类),提提 供供 CheckRoomIDValidCheckRoomIDValid 接口。接口。  int CPlayer::StandUp( int iSessionID )int CPlayer::StandUp( int iSessionID )  {{ iRet =iRet = m_Session.CheckValid(iSessionID);m_Session.CheckValid(iSessionID); If(iRet)If(iRet) {{ }}  }}
    20. 20.  这种是完全达到了隐藏实现,消除了代码这种是完全达到了隐藏实现,消除了代码 重复,又充分表意的目的。特别在此强调重复,又充分表意的目的。特别在此强调 释意接口。释意接口。  好的类 应该是每个函数都比较短,五,六好的类 应该是每个函数都比较短,五,六 十行。然后有二,三十个方法。这个类形十行。然后有二,三十个方法。这个类形 成一个接近封闭的类型。具有充分的自我成一个接近封闭的类型。具有充分的自我 表达能力。表达能力。
    21. 21. 实体表达的例子实体表达的例子  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  {{  }}
    22. 22.  同一个功能的另外一种写法 也是实际代码。同一个功能的另外一种写法 也是实际代码。  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  {{  }}  }}
    23. 23.  可以看出 抽取出了 日期类,用日期类可以看出 抽取出了 日期类,用日期类 来表达人的思想,而不是只记得使用哪来表达人的思想,而不是只记得使用哪 个个 APIAPI 来实现功能。来实现功能。  日期这个概念在这个需求里面是比较重日期这个概念在这个需求里面是比较重 要的一个概念。面向对象就表达出了这要的一个概念。面向对象就表达出了这 个概念个概念。。
    24. 24. 约束表达的例子约束表达的例子  有时候某些约束表达的是领域逻辑。通常有时候某些约束表达的是领域逻辑。通常 隐式的表达,将他们显示表达出来能够极隐式的表达,将他们显示表达出来能够极 大地改进设计。大地改进设计。  比如比如 QQGameQQGame 里面进入房间限制。里面进入房间限制。
    25. 25. 实际产品对进房需求的演化实际产品对进房需求的演化  第一个版本第一个版本 :: 限制一下玩家最低,最高积分限制一下玩家最低,最高积分 。。  第二个版本超级玩家和网管要优先进房第二个版本超级玩家和网管要优先进房  第三个版本如果是出租房间需要是承租方第三个版本如果是出租房间需要是承租方 才能进房才能进房  第四个版本如果是比赛房间需要是比赛方第四个版本如果是比赛房间需要是比赛方 才能进房才能进房  第五个版本需要拥有某种道具第五个版本需要拥有某种道具  第六个版本如果是欢乐场房间需要检查欢第六个版本如果是欢乐场房间需要检查欢 乐豆上下限制。乐豆上下限制。
    26. 26.  产品的需求演化说明进房约束是个热产品的需求演化说明进房约束是个热 点问题。点问题。  抽象出约束接口,把约束的增加,约抽象出约束接口,把约束的增加,约 束的实现,变更对束的实现,变更对进房主流程进房主流程屏蔽起屏蔽起 来。来。
    27. 27. 流程流程 (( 服务服务 )) 表达的例子表达的例子
    28. 28. 基本行为流程概念的表达,对于产品同事不断基本行为流程概念的表达,对于产品同事不断 提及到的流程概念表达。提及到的流程概念表达。
    29. 29. 行为概念流程表达的好处行为概念流程表达的好处
    30. 30. 把规格用对象来表达把规格用对象来表达  验证。验证。  选择选择 (( 查询查询 ))  按需创建按需创建
    31. 31. 隐含概念表达实例隐含概念表达实例  在在 QQGameQQGame 里面对房间模式的描述结构如里面对房间模式的描述结构如 下。不同的房间模式,具有不一样的基本下。不同的房间模式,具有不一样的基本 行为。行为。  我们通过不同的工厂实现来屏蔽掉这一层我们通过不同的工厂实现来屏蔽掉这一层 变化。不同的房间聚合不同的生成工厂。变化。不同的房间聚合不同的生成工厂。  房间模式是挖掘出来的概念,抽象工厂表房间模式是挖掘出来的概念,抽象工厂表 达出了这个概念。达出了这个概念。
    32. 32. OOOO 的五项技术原则是什么?的五项技术原则是什么? (讨论,提问)(讨论,提问)
    33. 33. OOOO 的五项技术原则的五项技术原则  单一职责—事情不要太复杂。单一职责—事情不要太复杂。  开闭原则—让易变的容易变化,不变的稳开闭原则—让易变的容易变化,不变的稳 定。定。  依赖倒置—让易变的依赖于稳定,而不是依赖倒置—让易变的依赖于稳定,而不是 相反。相反。  接口隔离接口隔离  可替代可替代
    34. 34. 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) : 接口隔离原则接口隔离原则 让李部长只负责开发吧,市场就让辛部长做吧让李部长只负责开发吧,市场就让辛部长做吧
    35. 35.  学习面向对象中最主要的一点就是,理解学习面向对象中最主要的一点就是,理解 面向对象原则。如果你还没有真正理解这面向对象原则。如果你还没有真正理解这 些原则,那你做出的设计可能不是最好的些原则,那你做出的设计可能不是最好的 设计,那你学习设计模式也不能真正理解设计,那你学习设计模式也不能真正理解 它的真谛。它的真谛。
    36. 36. 五项技术原则实例五项技术原则实例 -- 单一职责单一职责  实际代码例子实际代码例子  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];
    37. 37.  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:  };};
    38. 38.  职责表达了负责的变化,有多个维度职责表达了负责的变化,有多个维度 的职责,就有多个维度的变化的职责,就有多个维度的变化
    39. 39. 五项技术原则实例五项技术原则实例 -- 开闭原则开闭原则  QQGameQQGame 最经典的例子,最经典的例子, Main FrameMain Frame 可以可以 不动代码,游戏服务可以源源不断输出新的不动代码,游戏服务可以源源不断输出新的 游戏。觉得这个是最核心的规则。游戏。觉得这个是最核心的规则。(下图引(下图引 用自用自 zengyuzengyu 《《 QQGameQQGame 服务器架构技服务器架构技 术》)术》)
    40. 40. 五项技术原则实例五项技术原则实例 -- 依赖倒置依赖倒置  问题界面控件,比如问题界面控件,比如 Button,ListBoxButton,ListBox ,等。,等。 它们都是想做成通用的,也就是说和业务它们都是想做成通用的,也就是说和业务 逻辑不相关。但是事件响应 是通过界面控逻辑不相关。但是事件响应 是通过界面控 件传递到逻辑的。件传递到逻辑的。  问怎么做到界面控件和业务逻辑隔离?问怎么做到界面控件和业务逻辑隔离?
    41. 41. 经典的解决办法(参考经典的解决办法(参考 QQGameQQGame 大厅设计以及 《敏捷软件开大厅设计以及 《敏捷软件开 发》)发》)
    42. 42.  实际代码例子:实际代码例子:  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;  };};  五项技术原则实例五项技术原则实例 -- 接口隔离接口隔离
    43. 43. 五项技术原则实例五项技术原则实例 -- 可替换可替换  子类必须能够替换掉它们的基类型。子类必须能够替换掉它们的基类型。  问题:正方形是特殊的长方形吗?问题:正方形是特殊的长方形吗?
    44. 44. 从从 OOOO 看合理的分层结构看合理的分层结构
    45. 45.  用户界面层:负责向用户显示信息,解析用户命用户界面层:负责向用户显示信息,解析用户命 令。不一定面对的是人,可能是一条狗。令。不一定面对的是人,可能是一条狗。  应用层:定义软件可以完成的工作,指挥具有丰应用层:定义软件可以完成的工作,指挥具有丰 富含义的领域对象来解决问题。这个层要保持简富含义的领域对象来解决问题。这个层要保持简 练,不包括业务规则和知识,只是给下一层相互练,不包括业务规则和知识,只是给下一层相互 协作的领域对象协调任务,委托工作。协作的领域对象协调任务,委托工作。  领域层:负责表示业务概念,业务状况以及业务领域层:负责表示业务概念,业务状况以及业务 规则。业务软件核心。规则。业务软件核心。 将领域层分离出来至关重将领域层分离出来至关重 要。要。  基础结构层:为上层提供通用的技术能力:应用基础结构层:为上层提供通用的技术能力:应用 的消息发送,领域持久化,绘制窗口等。的消息发送,领域持久化,绘制窗口等。
    46. 46.  业务层根据业务层根据 Evans DDDEvans DDD ,可以再细分为应,可以再细分为应 用层和领域层两种,在业务层设计编码中用层和领域层两种,在业务层设计编码中 ,大量应用,大量应用 OOOO 设计原则和设计模式。设计原则和设计模式。  领域层定义:负责表达业务领域概念、业领域层定义:负责表达业务领域概念、业 务状态以及业务规 则,是整个业务软件核务状态以及业务规 则,是整个业务软件核 心和重点。心和重点。  应用层定义:负责完成功能,并且协调丰应用层定义:负责完成功能,并且协调丰 富的领域对象来实现功能,不能包括业务富的领域对象来实现功能,不能包括业务 规则,无业务状态;规则,无业务状态;
    47. 47. 从开发每个过程看从开发每个过程看 OOOO 方法论的方法论的 应用应用  1.1. 需求分析,用户活动图,软件需求规格需求分析,用户活动图,软件需求规格 说明书,领域建模。说明书,领域建模。 --OOA--OOA  2.2. 概要设计概要设计 // 详细设计—详细设计— OODOOD 分析和设计分析和设计 的边界很难明确分开。的边界很难明确分开。  3.3. 编码编码 // 测试测试 --OOP--OOP  4.4. 发布发布  5.5. 从从 11 再循环到再循环到 44
    48. 48. 需求分析需求分析 -OOA-OOA  第一步,建立用户活动图。不关注实现。第一步,建立用户活动图。不关注实现。 仅关注用户流程,实体。仅关注用户流程,实体。  第二步,画实体关系图,着重类概念,类第二步,画实体关系图,着重类概念,类 之间关系。之间关系。  第三步,画时序图,对关键活动,用例用第三步,画时序图,对关键活动,用例用 时序图来分析职责是否合理。时序图来分析职责是否合理。
    49. 49. OOAOOA 实例实例  系统需求:考评系统。 某系统需求:考评系统。 某 XXXX 公司要建立公司要建立 一个考评系统。一个考评系统。  大体上领导考虑 要从德智体等几个方面综大体上领导考虑 要从德智体等几个方面综 合考虑。合考虑。  德包括考勤,同事意见,领导意见等;智德包括考勤,同事意见,领导意见等;智 包括技术各项指标,比如操作系统,网络包括技术各项指标,比如操作系统,网络 ,领域理解等;体包括体育各项指标,比,领域理解等;体包括体育各项指标,比 如羽毛球,乒乓球等。如羽毛球,乒乓球等。  从这些方面给一个人打分。请用从这些方面给一个人打分。请用 OOOO 描述一描述一 下这个对象系统下这个对象系统 ..
    50. 50. 实例一:把各个实体概念及其之间关系表达出实例一:把各个实体概念及其之间关系表达出 来来
    51. 51. 实例二:进行抽象,使概念表达更具灵活性,实例二:进行抽象,使概念表达更具灵活性, 和可扩展性。和可扩展性。
    52. 52. 设计设计 -OOD-OOD  设计模式介绍 《深入浅出设计模式》 强烈设计模式介绍 《深入浅出设计模式》 强烈 推荐此书。推荐此书。  设计模式某个环境下,对某个设计问题的设计模式某个环境下,对某个设计问题的 一种解决方式的描述。一种解决方式的描述。  设计模式强调设计模式强调把容易变化和不变部分分离把容易变化和不变部分分离。。 让变化部分容易变化。让变化部分容易变化。  在日常开发中,找到变化点,积累变化面在日常开发中,找到变化点,积累变化面 是重要的。是重要的。
    53. 53.  模板方法模板方法  观察者观察者  抽象工厂抽象工厂  桥桥  职责链职责链  组合组合  ReactorReactor  acac
    54. 54. 设计模式实例—模板方法设计模式实例—模板方法  在一个框架里面,比如在一个框架里面,比如 MFC,MFC, 要做本身框架要做本身框架 的初始化代码,又要给不同的业务留下初的初始化代码,又要给不同的业务留下初 始化各自业务的空间。同时框架代码是以始化各自业务的空间。同时框架代码是以 二进制形式发布的,不能在里面添加代码。二进制形式发布的,不能在里面添加代码。 怎么办?怎么办?  一个一个 MFCMFC 应用程序的应用程序的 WinMainWinMain 函数哪里去函数哪里去 了?了?
    55. 55. MFCMFC 的解决实例的解决实例
    56. 56. 模板方法类图结构模板方法类图结构
    57. 57. 设计模式实例—观察者设计模式实例—观察者  一个分层的架构,越下层的结构往往越通一个分层的架构,越下层的结构往往越通 用,下层不能依赖于上层。但是下层又有用,下层不能依赖于上层。但是下层又有 东西要通知上层。比如 网络层不能依赖于东西要通知上层。比如 网络层不能依赖于 领域层,问怎么能做到?领域层,问怎么能做到?
    58. 58. 观察者标准类图观察者标准类图
    59. 59. 观察者实际代码例子观察者实际代码例子  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;  };}; 这个实例中,命令是属于基础设施层的东西,但是要这个实例中,命令是属于基础设施层的东西,但是要 通知上层业务逻辑,自己的状态变迁。所以使用观察通知上层业务逻辑,自己的状态变迁。所以使用观察
    60. 60. 设计模式实例—抽象工厂设计模式实例—抽象工厂  OOOO 比较强调比较强调创建创建这个行为。一方面创建有这个行为。一方面创建有 时候本身很复杂;另一方面,程序很多的时候本身很复杂;另一方面,程序很多的 灵活性需要通过一种合适的创建方式才能灵活性需要通过一种合适的创建方式才能 获得。获得。  当当 newnew 一个对象的时候,写一个对象的时候,写 newnew 的这个代的这个代 码的类就产生了对码的类就产生了对 newnew 出对象的依赖。我出对象的依赖。我 们当然希望频繁变化的逻辑不要被上层依们当然希望频繁变化的逻辑不要被上层依 赖。赖。  那么为了能做到这一点,就需要有合适的那么为了能做到这一点,就需要有合适的 创建方式。创建方式。
    61. 61. 简单的工厂简单的工厂
    62. 62. 抽象工厂抽象工厂
    63. 63.  1.1. 抽象工厂强调的是一系列相关的变化聚抽象工厂强调的是一系列相关的变化聚 合在一起,有几个系列,就有几个具体的合在一起,有几个系列,就有几个具体的 工厂。工厂。  2.2. 切换的时候,打一个开关就可以了。使切换的时候,打一个开关就可以了。使 得变化相当的容易,明显。得变化相当的容易,明显。  3.3. 工厂创建的东西互相不干扰。各干各的工厂创建的东西互相不干扰。各干各的 活。活。 抽象工厂特征抽象工厂特征
    64. 64. 设计模式实例—桥设计模式实例—桥  有一类模块,对外提供抽象接口,实现一有一类模块,对外提供抽象接口,实现一 个功能。它有两个维度的变化。个功能。它有两个维度的变化。  一个维度是提供的抽象功能,可能在变化一个维度是提供的抽象功能,可能在变化 。。  另一个维度是实现抽象功能的实现方式也另一个维度是实现抽象功能的实现方式也 会变化。会变化。  另外一种情况是提供的抽象功能给外部接另外一种情况是提供的抽象功能给外部接 口,不希望这个接口频繁变化,给外部带口,不希望这个接口频繁变化,给外部带 来困扰。来困扰。  问怎么实现这个需求?问怎么实现这个需求?
    65. 65. ACE Reactor-ACE Reactor- 实现视图实现视图
    66. 66. 设计模式实例设计模式实例 -- 职责链职责链  应用层协议确定分发问题:应用层协议确定分发问题:  比如我们要分析网络上各种应用层协议内比如我们要分析网络上各种应用层协议内 容。包括容。包括 smtp,http,pop3,ftpsmtp,http,pop3,ftp 等等。应用层协等等。应用层协 议是会增加的。现在问题是一个网络连接议是会增加的。现在问题是一个网络连接 ,我们无法知道它走的是什么协议。,我们无法知道它走的是什么协议。  一个简单的端口是无法准确判断的。一个简单的端口是无法准确判断的。  问怎么做这个问题的设计方案。问怎么做这个问题的设计方案。
    67. 67. 职责链好处如下职责链好处如下  各个协议分开,各干各的活 不会互相干扰。各个协议分开,各干各的活 不会互相干扰。 做到高内聚,低耦合。做到高内聚,低耦合。  新协议的增加是很简单的,甚至可以做到新协议的增加是很简单的,甚至可以做到 动态增加。可以做到开闭原则。动态增加。可以做到开闭原则。
    68. 68. 设计模式实例设计模式实例 -- 组合模式组合模式  请用请用 OOOO 描述描述 QQGameQQGame 的目录树结构。的目录树结构。  请在这个描述结构上计算目录树各层人数请在这个描述结构上计算目录树各层人数 。。
    69. 69. 设计模式实例—设计模式实例— ReactorReactor  做许多网络服务器做许多网络服务器 // 客户端的时候,基本上客户端的时候,基本上 每一个都会用到每一个都会用到 selectselect 或类似功能函数。多或类似功能函数。多 线程线程 // 多进程模式除外。多进程模式除外。  当当 selectselect 检测到某个检测到某个 fdfd 有数据的时候,我有数据的时候,我 们再去读取数据。基本上这部分代码和我们再去读取数据。基本上这部分代码和我 们的业务逻辑代码混合在一起。们的业务逻辑代码混合在一起。  在一个网络服务器里面,基本都需要定时在一个网络服务器里面,基本都需要定时 器的操作。器的操作。  这些每一个网络服务器都需要的东西,能这些每一个网络服务器都需要的东西,能 否提取出来?形成一个通用解决框架。否提取出来?形成一个通用解决框架。
    70. 70. 注意注意 ReactorReactor 对概念的抽象,和应用的分层隔离。对概念的抽象,和应用的分层隔离。 这些经典的手段。这些经典的手段。
    71. 71. 设计模式实例—异步命令模式设计模式实例—异步命令模式  高效的网络服务器高效的网络服务器 // 客户端经常遇到异步操客户端经常遇到异步操 作问题。作问题。  异步响应回来的时候,如何知道异步请求异步响应回来的时候,如何知道异步请求 时候的状态是什么一直是个问题。时候的状态是什么一直是个问题。  这个操作超时,完成,失败和业务逻辑的这个操作超时,完成,失败和业务逻辑的 隔离也存在问题。隔离也存在问题。  ACTACT 异步回调异步回调 TOKENTOKEN 的概念。的概念。
    72. 72. 异步命令模式框图异步命令模式框图
    73. 73. 时序图时序图  将异步操作和业务逻辑隔离。将异步操作和业务逻辑隔离。  利用异步回调利用异步回调 TOKENTOKEN 找到响应消息观察找到响应消息观察 者。通用解决方式。者。通用解决方式。  利用命令保存异步操作请求时候状态。方利用命令保存异步操作请求时候状态。方 便响应回来时候恢复。便响应回来时候恢复。
    74. 74. 谢谢谢谢 Q&AQ&A

    ×