Skip to content

Commit

Permalink
看懂UML类图和时序图
Browse files Browse the repository at this point in the history
  • Loading branch information
me115 committed Nov 12, 2014
1 parent 24b1f02 commit 01960a1
Show file tree
Hide file tree
Showing 30 changed files with 241 additions and 47 deletions.
Binary file added _static/State_run.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _static/Strategy_run.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _static/uml_AbatractClass.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _static/uml_aggregation.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _static/uml_association.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _static/uml_class_struct.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _static/uml_composition.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _static/uml_dependency.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _static/uml_generalization.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _static/uml_generalize.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _static/uml_realize.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions behavioral_patterns/behavioral.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,6 @@
command
mediator
observer
state
strategy

74 changes: 60 additions & 14 deletions behavioral_patterns/state.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,53 @@
- ConcreteState: 具体状态类


.. image:: /_static/SimpleFactory.jpg
.. image:: /_static/State.jpg


时序图
--------------------
.. image:: /_static/seq_SimpleFactory.jpg
.. image:: /_static/seq_State.jpg


既然是状态模式,加上状态图,对状态转换间的理解会清晰很多:

.. image:: /_static/State1.png

代码分析
--------------------
.. literalinclude:: /code/SimpleFactory/Factory.cpp
.. literalinclude:: /code/State/main.cpp
:language: cpp
:linenos:
:lines: 1-

.. literalinclude:: /code/State/Context.h
:language: cpp
:linenos:
:lines: 1-
:emphasize-lines: 20-24

.. literalinclude:: /code/State/Context.cpp
:language: cpp
:linenos:
:lines: 1-
:emphasize-lines: 19-25

.. literalinclude:: /code/State/ConcreteStateA.h
:language: cpp
:linenos:
:lines: 1-

.. literalinclude:: /code/State/ConcreteStateA.cpp
:language: cpp
:linenos:
:lines: 1-10,24-
:emphasize-lines: 12-19
:lines: 1-
:emphasize-lines: 30-33


运行结果:

.. image:: /_static/State_run.jpg


模式分析
--------------------
Expand All @@ -51,14 +82,30 @@
在状态模式结构中需要理解环境类与抽象状态类的作用:

- 环境类实际上就是拥有状态的对象,环境类有时候可以充当状态管理器(State Manager)的角色,可以在环境类中对状态进行切换操作。
- 抽象状态类可以是抽象类,也可以是接口,不同状态类就是继承这个父类的不同子类,状态类的产生是由于环境类存在多个状态,同时还满足两个条件: 这些状态经常需要切换,在不同的状态下对象的行为不同。因此可以将不同对象下的行为单独提取出来封装在具体的状态类中,使得环境类对象在其内部状态改变时可以改变它的行为,对象看起来似乎修改了它的类,而实际上是由于切换到不同的具体状态类实现的。由于环境类可以设置为任一具体状态类,因此它针对抽象状态类进行编程,在程序运行时可以将任一具体状态类的对象设置到环境类中,从而使得环境类可以改变内部状态,并且改变行
为。
- 抽象状态类可以是抽象类,也可以是接口,不同状态类就是继承这个父类的不同子类,状态类的产生是由于环境类存在多个状态,同时还满足两个条件: 这些状态经常需要切换,在不同的状态下对象的行为不同。因此可以将不同对象下的行为单独提取出来封装在具体的状态类中,使得环境类对象在其内部状态改变时可以改变它的行为,对象看起来似乎修改了它的类,而实际上是由于切换到不同的具体状态类实现的。由于环境类可以设置为任一具体状态类,因此它针对抽象状态类进行编程,在程序运行时可以将任一具体状态类的对象设置到环境类中,从而使得环境类可以改变内部状态,并且改变行为。

实例
--------------------
TCPConnection:
TCPConnection

这个示例来自《设计模式》,展示了一个简化版的TCP协议实现;
TCP连接的状态有多种可能,状态之间的转换有相应的逻辑前提;
这是使用状态模式的场合;


状态图:

.. image:: /_static/State2.png

结构图:

.. image:: /_static/State_eg.jpg


时序图:

.. image:: /_static/seq_State_eg.jpg

示例来自《设计模式》

优点
--------------------
Expand Down Expand Up @@ -97,13 +144,12 @@ TCPConnection:
--------------------
共享状态

- 在有些情况下多个环境对象需要共享同一个状态,如果希望在系统中实现多个环境对象实例共享一个或多
个状态对象,那么需要将这些状态对象定义为环境的静态成员对象。
- 在有些情况下多个环境对象需要共享同一个状态,如果希望在系统中实现多个环境对象实例共享一个或多个状态对象,那么需要将这些状态对象定义为环境的静态成员对象。

简单状态模式与可切换状态的状态模式

- (1) 简单状态模式:简单状态模式是指状态都相互独立,状态之间无须进行转换的状态模式,这是最简单的一种状态模式。对于这种状态模式,每个状态类都封装与状态相关的操作,而无须关心状态的切换,可以在客户端直接实例化状态类,然后将状态对象设置到环境类中。如果是这种简单的状态模式,它遵循“开闭原则”,在客户端可以针对抽象状态类进行编程,而将具体状态类写到配置文件中,同时增加新的状态类对原有系统也不造成任何影响。
2) 可切换状态的状态模式:大多数的状态模式都是可以切换状态的状态模式,在实现状态切换时,在具体状态类内部需要调用环境类Context的setState()方法进行状态的转换操作,在具体状态类中可以调用到环境类的方法,因此状态类与环境类之间通常还存在关联关系或者依赖关系。通过在状态类中引用环境类的对象来回调环境类的setState()方法实现状态的切换。在这种可以切换状态的状态模式中,增加新的状态类可能需要修改其他某些状态类甚至环境类的源代码,否则系统无法切换到新增状态。
简单状态模式与可切换状态的状态模式
1) 简单状态模式:简单状态模式是指状态都相互独立,状态之间无须进行转换的状态模式,这是最简单的一种状态模式。对于这种状态模式,每个状态类都封装与状态相关的操作,而无须关心状态的切换,可以在客户端直接实例化状态类,然后将状态对象设置到环境类中。如果是这种简单的状态模式,它遵循“开闭原则”,在客户端可以针对抽象状态类进行编程,而将具体状态类写到配置文件中,同时增加新的状态类对原有系统也不造成任何影响。
2) 可切换状态的状态模式:大多数的状态模式都是可以切换状态的状态模式,在实现状态切换时,在具体状态类内部需要调用环境类Context的setState()方法进行状态的转换操作,在具体状态类中可以调用到环境类的方法,因此状态类与环境类之间通常还存在关联关系或者依赖关系。通过在状态类中引用环境类的对象来回调环境类的setState()方法实现状态的切换。在这种可以切换状态的状态模式中,增加新的状态类可能需要修改其他某些状态类甚至环境类的源代码,否则系统无法切换到新增状态。

总结
--------------------
Expand Down
32 changes: 26 additions & 6 deletions behavioral_patterns/strategy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,40 @@
- ConcreteStrategy: 具体策略类


.. image:: /_static/SimpleFactory.jpg
.. image:: /_static/Strategy.jpg


时序图
--------------------
.. image:: /_static/seq_SimpleFactory.jpg
.. image:: /_static/seq_Strategy.jpg

代码分析
--------------------
.. literalinclude:: /code/SimpleFactory/Factory.cpp
.. literalinclude:: /code/Strategy/main.cpp
:language: cpp
:linenos:
:lines: 1-10,24-
:emphasize-lines: 12-19
:emphasize-lines: 10-17

.. literalinclude:: /code/Strategy/Context.h
:language: cpp
:linenos:

.. literalinclude:: /code/Strategy/Context.cpp
:language: cpp
:linenos:
:emphasize-lines: 16-22

.. literalinclude:: /code/Strategy/ConcreteStrategyA.h
:language: cpp
:linenos:

.. literalinclude:: /code/Strategy/ConcreteStrategyA.cpp
:language: cpp
:linenos:

运行结果:

.. image:: /_static/Strategy_run.jpg


模式分析
Expand All @@ -52,7 +72,7 @@

- 在策略模式中,应当由客户端自己决定在什么情况下使用什么具体策略角色。

-策略模式仅仅封装算法,提供新算法插入到已有系统中,以及老算法从系统中“退休”的方便,策略模式并不决定在何时使用何种算法,算法的选择由客户端来决定。这在一定程度上提高了系统的灵活性,但是客户端需要理解所有具体策略类之间的区别,以便选择合适的算法,这也是策略模式的缺点之一,在一定程度上增加了客户端的使用难度。
- 策略模式仅仅封装算法,提供新算法插入到已有系统中,以及老算法从系统中“退休”的方便,策略模式并不决定在何时使用何种算法,算法的选择由客户端来决定。这在一定程度上提高了系统的灵活性,但是客户端需要理解所有具体策略类之间的区别,以便选择合适的算法,这也是策略模式的缺点之一,在一定程度上增加了客户端的使用难度。

实例
--------------------
Expand Down
6 changes: 0 additions & 6 deletions code/State/ConcreteStateA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,11 @@ using namespace std;

State * ConcreteStateA::m_pState = NULL;
ConcreteStateA::ConcreteStateA(){

}



ConcreteStateA::~ConcreteStateA(){

}


State * ConcreteStateA::Instance()
{
if ( NULL == m_pState)
Expand All @@ -32,7 +27,6 @@ State * ConcreteStateA::Instance()
return m_pState;
}


void ConcreteStateA::handle(Context * c){
cout << "doing something in State A.\n done,change state to B" << endl;
c->changeState(ConcreteStateB::Instance());
Expand Down
5 changes: 0 additions & 5 deletions code/State/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,13 @@ Context::Context(){
m_pState = ConcreteStateA::Instance();
}



Context::~Context(){

}


void Context::changeState(State * st){
m_pState = st;
}


void Context::request(){
m_pState->handle(this);
}
10 changes: 5 additions & 5 deletions code/State/main.cfp
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@
<File>Context.h</File>
<File>State.cpp</File>
<File>State.h</File>
<Attribute topline="1" x="15" y="13">main.cpp</Attribute>
<Attribute topline="1" x="20" y="10">ConcreteStateA.cpp</Attribute>
<Attribute topline="7" x="25" y="19">ConcreteStateA.h</Attribute>
<Attribute topline="1" x="6" y="13">main.cpp</Attribute>
<Attribute topline="13" x="3" y="26">ConcreteStateA.cpp</Attribute>
<Attribute topline="7" x="26" y="25">ConcreteStateA.h</Attribute>
<Attribute topline="5" x="1" y="10">ConcreteStateB.cpp</Attribute>
<Attribute topline="4" x="28" y="17">ConcreteStateB.h</Attribute>
<Attribute topline="4" x="1" y="15">Context.cpp</Attribute>
<Attribute topline="7" x="17" y="21">Context.h</Attribute>
<Attribute topline="10" x="27" y="13">Context.cpp</Attribute>
<Attribute topline="13" x="24" y="26">Context.h</Attribute>
<Attribute topline="10" x="1" y="26">State.cpp</Attribute>
<Attribute topline="1" x="1" y="11">State.h</Attribute>
<FolderState>111</FolderState>
Expand Down
6 changes: 6 additions & 0 deletions code/State/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ using namespace std;

int main(int argc, char *argv[])
{
char a = '0';
if('0' == a)
cout << "yes" << endl;
else
cout << "no" << endl;

Context * c = new Context();
c->request();
c->request();
Expand Down
Binary file modified code/State/mingw5/ConcreteStateA.o
Binary file not shown.
Binary file modified code/State/mingw5/Context.o
Binary file not shown.
Binary file modified code/State/mingw5/main.exe
Binary file not shown.
Binary file modified code/State/mingw5/main.o
Binary file not shown.
2 changes: 0 additions & 2 deletions code/Strategy/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,12 @@ Context::Context(){
}

Context::~Context(){

}

void Context::algorithm(){
m_pStrategy->algorithm();
}


void Context::setStrategy(Strategy* st){
m_pStrategy = st;
}
Expand Down
10 changes: 5 additions & 5 deletions code/Strategy/main.cfp
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
<File>Context.h</File>
<File>Strategy.cpp</File>
<File>Strategy.h</File>
<Attribute topline="13" x="1" y="23">main.cpp</Attribute>
<Attribute topline="13" x="1" y="19">ConcreteStrategyA.cpp</Attribute>
<Attribute topline="7" x="1" y="15">ConcreteStrategyA.h</Attribute>
<Attribute topline="1" x="31" y="10">main.cpp</Attribute>
<Attribute topline="7" x="21" y="20">ConcreteStrategyA.cpp</Attribute>
<Attribute topline="7" x="47" y="23">ConcreteStrategyA.h</Attribute>
<Attribute topline="13" x="1" y="28">ConcreteStrategyB.cpp</Attribute>
<Attribute topline="1" x="21" y="8">Context.cpp</Attribute>
<Attribute topline="10" x="24" y="25">Context.h</Attribute>
<Attribute topline="7" x="2" y="22">Context.cpp</Attribute>
<Attribute topline="10" x="14" y="13">Context.h</Attribute>
<Attribute topline="1" x="1" y="17">Strategy.h</Attribute>
<FolderState>111</FolderState>
<DefConfig>mingw5</DefConfig>
Expand Down
Binary file modified code/Strategy/mingw5/ConcreteStrategyA.o
Binary file not shown.
Binary file modified code/Strategy/mingw5/Context.o
Binary file not shown.
Binary file modified code/Strategy/mingw5/main.exe
Binary file not shown.
Binary file modified design_patterns.EAP
Binary file not shown.
8 changes: 4 additions & 4 deletions index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@
架构模式、分析模式和过程模式等,实际上,在软件生存期的每一
个阶段都存在着一些被认同的模式。


本书将通过图形和代码来解析设计模式;
每个模式都有相应的时序图来介绍其如何运行;
本书使用图形和代码结合的方式来解析设计模式;
每个模式都有相应的对象结构图和时序图来介绍其如何运行;(在状态模式中,
我们还会用到状态图,这种图的使用对于理解状态的转换非常直观)

为了让大家能读懂UML结构图,在最前面会有一张UML图形符号简介;


.. toctree::
:maxdepth: 2

read_xml
read_uml
creational_patterns/creational
structural_patterns/structural
behavioral_patterns/behavioral
Expand Down
Loading

0 comments on commit 01960a1

Please sign in to comment.