手机内存卡系统技术架构探索

这一周来为了验证手机内存卡系统的技术框架可行性,探索和初步学习了各种图形界面和编程语言等各种选择的适用性。包括:tinycore linux, fltk, gtk, qt, zenity, c, c++, bash, glade 等。最后决定用 tinycore linux + gtk2 + bash + zenity 来实现手机内存卡系统的 Demo 0.1 版本。
Continue reading "手机内存卡系统技术架构探索"

GoF的《设计模式》之入门介绍

转载请注明本文原始出处:GoF设计模式之入门介绍: http://java.learndiary.com/diaries/3150.jsp。本文在原始出处随时更新,欢迎批评指正和讨论。

--JAVA学习日记 littlebat 2007.04.02 16:33

正文:

*********************************************************************

用了一周多时间把这章看了一遍,并结合其中的内容把自己原来记的学习Thinking in Patterns with Java的日记复习了一下,感觉对各种设计模式的印象又清楚了一些,提起某个模式的名字大概知道了是怎么一回事。下面记下学习这章中的一些知识点和心得如下:

要做一个好的设计是困难的,设计模式的作用就是把这些被反复证明了的好的设计以一个统一的形式归纳记录下来。一旦一个设计的“套路“被证明是有效的,就像一个“浪漫小说“那样有一套固定的模式,可以反复的套来用。GoF总结的设计模式只是那些专家们知道的一个片断,还有像分布式编程、实时编程、设备驱动编程、面向特定应用领域编程等等的设计模式还有待别人去归纳整理(littlebat注:不知道这些领域的设计模式现在有没有?情况如何?学习领域现在不知有没有设计模式?也许学习日记可以在这方面看一看)。

1、什么是设计模式?

(The design patterns in this book are descriptions of communicating objects and classes that are customized to solve a general design problem in a particular context.)设计模式是在特定的环境中用来解决通用的设计问题的相互交流的对象和类。它的粒度不是细到讲怎么样实现一个链、一个哈希表,也不是粗到整个应用或者子系统。一个模式有4个基本元素:名称、解决的问题、解决的方案、结果。设计模式的实现的复杂程度跟选择的实现语言关系很大,所以有的设计模式在一种语言中实现起来很复杂,而在另一种语言中实现起来很简单,甚至有些模式已经被某种语言内置支持(littlebat注:像在Thinking in Patterns with Java中读到的那样,像Iterator, Observer, Adapter, Proxy等模式就在Java语言中内置支持,另外,Java中的clone()方法是否是prototype模式、Java的package是否是Facade模式、而Java的序列化技术是否是Memento的模式、Comparator是否是Strategy模式的内置支持还不是很清楚?)。这本书主要是采用C++(littlebat注:要复习一下c++语法了) 和 SmallTalk来实现例程。

2、Smalltalk MVC里的设计模式:

这一节分析了SmallTalk的MVC框架(littlebat注:Java中的Struts也是一种MVC实现)所涉及到的设计模式包括:Observer, Composite, Strategy, Factory method, Decorator等等。

3、描述设计模式:

这本书以一套固定的模版来描述一个设计模式,包括:名称和分类、目的、别名、动机(Motivation)、适用性、结构、参与的对象和类、参与者的交互、后果、实现、例程、已知的使用例子、相关模式。(littlebat注:其中为阐述结构,使用了现在UML的前身包含的一些技术,如OMT,交互图,序列图等等。。。我想,这些技术与UML应该差不多,有些区别通过看其它相关的内容也应该可以知道的。另外,UML好像是1997年才正式发布的?)

4、设计模式的目录:

这一节列出全部23种设计模式的目录和简短的描述,Abstract Factory (87), Adapter (139), Bridge (151),

Builder (97), Chain of Responsibility (223), Command (233), Composite (163), Decorator (175), Facade (185), Factory Method (107), Flyweight (195), Interpreter (243), Iterator (257), Mediator (273), Memento (283), Observer (293), Prototype (117), Proxy (207), Singleton (127), State (305), Strategy (315), Template Method (325), Visitor (331)。

组织目录:

GoF主要用两个标准来划分设计模式,一个标准是目的,分为:创建、结构、行为的目的。如下:

创建的目的:

Factory Method (107)

Abstract Factory (87)

Builder (97)

Prototype (117)

Singleton (127)

结构的目的:

Adapter (139)

Bridge (151)

Composite (163)

Decorator (175)

Facade (185)

Proxy (207)

行为的目的:

Interpreter (243)

Template Method (325)

Chain of Responsibility (223)

Command (233)

Iterator (257)

Mediator (273)

Memento (283)

Flyweight (195)

Observer (293)

State (305)

Strategy (315)

Visitor (331)

第二个分类的标准是模式使用的范围,包括:类的范围、对象的范围。如下:

类的范围:

Factory Method (107) Adapter (139) Interpreter (243)  Template Method (325)

对象的范围:

Abstract Factory (87)

Builder (97)

Prototype (117)

Singleton (127)

 Adapter (139)

Bridge (151)

Composite (163)

Decorator (175)

Facade (185)

Proxy (207)

 Chain of Responsibility (223)

Command (233)

Iterator (257)

Mediator (273)

Memento (283)

Flyweight (195)

Observer (293)

State (305)

Strategy (315)

Visitor (331)

书中还提出了也有其它的方式来组织设计模式,如有的设计模式经常放在一起用,有的可以互换,有的设计结果的结构相似等等。并特别的提出了一种根据设计模式间的关系来组织目录的方式,这就是很重要的设计模式的关系图(Figure 1.1,我把这张图放在了后面的附图中:图1.1)。

(littlebat注:我觉得关系图中的关系主要是一种模式使用了另一种模式的关系,如:图中的Composite模式使用了Iterator模式来遍历子对象,Iterator使用了Memento来保存遍历的状态。

另外,在Thinking in Patterns with Java中的分类是根据设计模式解决问题的性质,我本来以为在GoF的设计模式中没有按问题分类,结果是GoF把这种分类放在了设计模式怎样解决设计问题的下一节中。

另外,我发现了一些现在看来在这两本书中有点矛盾的地方:如在Bruce先生的书中说Decorater模式是解决类太多的问题(Thinking in Patterns chapter 9: too many),Bridge模式主要在用于代码的组织上(Thinking in Patterns chapter 10: Connecting different types),而在GoF的书上把这两种模式都归为在对象范围内应用的模式。也许他们是从不同的角度来说的,还需要进一步学习。

5、设计模式怎样解决设计问题

这一节是这一章中内容最多也算最重要的一节吧。它讲了oop设计者可能面临的各种设计问题和设计模式怎样帮助设计者解决这些设计问题。这些设计问题如下:

1)、找出恰当的对象

2)、决定对象粒度

3)、指定对象接口

4)、指定对象实现

   (1)类继承对接口继承

   (2)编程到接口而不是实现

5)、使重用技术运用起来

   (1)继承对组合

    要更多的使用组合

   (2)代理

   (3)继承对参数化类型

    取决于实现的系统

6)、关联运行时和编译时结构

7)、设计成适应改变的系统

   在这一节中指出了一些系统不易改变(灵活性差,稍有扩展和改变引发代价较大的重新设计)的问题和针对相应问题的设计模式:

    (1)精确的指定类来创建对象

       Design patterns: Abstract Factory (87), Factory Method (107), Prototype (117).

    (2)依赖特定的方法

       Design patterns: Chain of Responsibility (223), Command (233).

    (3)依赖硬件和软件平台

        Design patterns: Abstract Factory (87), Bridge (151).

    (4)依赖对象表现或实现

        Design patterns: Abstract Factory (87), Bridge (151), Memento (283), Proxy (207).

    (5)算法依赖

        Design patterns: Builder (97), Iterator (257), Strategy (315), Template Method (325), Visitor (331).

    (6)紧耦合

        Design patterns: Abstract Factory (87), Bridge (151), Chain of Responsibility (223), Command (233), Facade (185), Mediator (273), Observer (293).

    (7)用继承扩展功能

        Design patterns: Bridge (151), Chain of Responsibility (223), Composite (163), Decorator (175), Observer (293), Strategy (315).

    (8)不能方便的改变类

        Design patterns: Adapter (139), Decorator (175), Visitor (331).

   而对于这种改变灵活性的要求程度如何取决于所实现的系统,按灵活性要求从低到高分为3类系统:

    (1)应用程序

    (2)工具包

    (3)框架

     框架和模式的区别:

          1>、设计模式更抽象

          2>、设计模式是要小一些的结构元素

          3>、设计模式更通用化一些

这一节可以同Bruce先生从解决问题对设计模式进行的分类比较着看,Bruce先生根据设计模式解决的问题分成:

1>、Object quantity: Singleton

2>、Object decoupling: Proxy, State, Iterator

3>、Factoring commonality: Strategy, Policy, Template method

4>、Encapsulating creation: Factory method, Abstract factory

5>、Specialized creation: Prototype, Builder

6>、Too many: Flyweight(too many objects), Decorator(too many classes)

7>、Connecting different types: Adapter, Bridge

8>、Flexible structure: Composite

9>、System decoupling: Observer, Mediator

10>、Reducing interface complexity: Facade

11>、Algorithmic partitioning: Command, Chain of responsibility

12>、Externalizing object state: Memento

13>、Complex interactions: Visitor

14>、Multiple languages: Interpreter

现在看来,好像Bruce先生的针对解决问题的分类的可操作性要简单易懂一些。我印象比较深刻的就是那个Too many,例如:如果我在一个设计对应于现实对象的静态结构中找出了过多的类(像Bruce先生举的那个咖啡馆里的咖啡种类),我可以第一时间想到:这么多的类是不是用Decorator减少一些哟?当然,我还没有真正的实践过设计模式,也许真到那时使用这些设计模式也不是这么一回事。先记在这里回头再说吧。

另外,在这一节中有一些东西需要更进一步的学习,如class和type的区别,UML和OMT的区别?怎样用设计模式解决问题?还有,这一节的内容很多,不少东西都是粗粗读过,还需要在读完全书后再回过头来反复读,正如作者说,这不是一本看完一遍就扔在一边的书。

6、怎样选择一个设计模式

1)、想想设计模式怎样解决设计问题的

2)、查一下设计模式的意图

3)、研究一下设计模式的相互关系

4)、研究一下目的类似的设计模式

5)、检查一下引起重新设计的原因

6)、考虑一下你的设计中的变化因素

下面是书中的一个表,列出3种目的的设计模式可以解决的系统中的变化因素,描述格式是:设计模式      设计中可能变化的方面

1>,Creational

Abstract Factory (87) families of product objects

Builder (97) how a composite object gets created

Factory Method (107) subclass of object that is instantiated

Prototype (117) class of object that is instantiated

Singleton (127) the sole instance of a class

2>,Structural

Adapter (139) interface to an object

Bridge (151) implementation of an object

Composite (163) structure and composition of an object

Decorator (175) responsibilities of an object without subclassing

Facade (185) interface to a subsystem

Flyweight (195) storage costs of objects

Proxy (207) how an object is accessed; its location

3>,Behavioral

Chain of Responsibility (223) object that can fulfill a request

Command (233) when and how a request is fulfilled

Interpreter (243) grammar and interpretation of a language

Iterator (257) how an aggregate's elements are accessed, traversed

Mediator (273) how and which objects interact with each other

Memento (283) what private information is stored outside an object, and when

Observer (293) number of objects that depend on another object; how the dependent objects stay up to date

State (305) states of an object

Strategy (315) an algorithm

Template Method (325) steps of an algorithm

Visitor (331) operations that can be applied to object(s) without changing their class(es)

7)、怎样使用一个设计模式

讲当你选择了一个设计模式后怎样使用它。

    (1)把这个设计模式通读一遍

    (2)研究结构、参与者、交互部分

    (3)看例程部分

    (4)为设计模式中的参与者选定名字

    (5)定义类

    (6)为设计模式中的方法(操作)定义具体到应用的名字

    (7)实现模式中的方法

最后,这节讲了一个非常重要的观点,设计模式不能滥用,因为为达到灵活性等设计模式的使用常引入间接的附加的层次,这使系统变得复杂或(和)影响性能。只有设计模式提供的灵活性是系统真正需要的时候才使用它。后面的章节对评价一个设计模式的损益很有用。

*********************************************************************

附图:图1.1

GoF的《设计模式》之前言、序言和用户指导

从书的前言可知,GoF设计模式是那四个家伙在1994年8月完成的。这本书是给对面向对象设计有一些基本了解的朋友读的。使用设计模式的目的是为了使设计更加灵活、模块化、可重用、可理解。这本书不是那种读一遍就扔在一边的书,所以你不要因为你读一遍而不完全理解它们而担心,就是作者们自己在第一次写的时候也没有完全理解(littlebat注:所以说,把心得和疑惑诉诸文字的过程也是理解和深化的学习过程,这也是我写学习日记的主要因素之一,还有一个主要因素是备忘等等)!这是一本值得反复阅读的书。这本书从酝酿到完成用了很多时间,书的四个作者来自四个国家,并且得到了许多人的帮助和支持(littlebat注:有两大段鸣谢的人名)。这本书只是反应了作者当时对设计的一种思考的记录,必将随着时间的推进而不断发展(littlebat 注:从我在网上看到的的情况来看确实如此,各种语言的设计模式版本出现,各种新的设计模式应该也在发明中,可以说有许多人在用设计模式吃饭,你看看太多的相关书籍就知道了,不过我觉得GoF的设计模式才是它们被公认的源头,所以我就想试着读读这本书的英文电子版了,有必要的话再去买一本英文版的或翻译版纸质书)。

从CD的前言可知,CD版(电子版)的书是在应许多人的反馈于书发行后3年的1997年发行的。CD版的书可以使查阅和使用更方便。这篇前言也总结了他们的书发行3年来的巨大成功,确实达成了他们当初的心愿:使更多的软件工程师从中获益。同样,这篇前言鸣谢了对CD版发行有帮助的人。(littlebat注:这个CD版的好是好,只不过用了javascript和java applet小程序技术,让我在486的古董机在linux控制台下w3m浏览器中无法阅读,特地为读这本书装了一个windows97,当初他们就没有考虑过有人在控制台下读这本书吧。不过,也知足了,况且我目前还是盗版用户呢。)

然后是Rational的那个OOP方面的大腕Grady Booch给他们作的序,开头绕了一大段计算机考古专家考查计算机历史“地层”的话,让我看不懂。他的序的意思就是:GoF的设计模式很成功,能从他们那里学到很多,他们的贡献可以在计算机的发展历史上记上一笔了。哦,这里提到那四个家伙的名字:Erich, Richard, Ralph, and John(littlebat注:好像有个家伙现在已经不在人世了,“四人帮”变成“三人帮”了)。

下面这篇用户指南值得好好读一读,它先是讲了一下这本书分为两大部分:第一部分(第1、2章)是基本概念和案例,第二部分(3、4、5章)是具体的分为3类的23种设计模式;然后它给了你几种阅读23种设计模式的方式,你可以根据自己的实际情况选择一下。这几种方式大概包括:

1、从头到尾依次阅读;

2、顺着设计模式之间的关系读(有一个关系图:Figure 1.1 (page 12) );

3、可以按所着手解决的问题的分类来读(Section 1.6 (page 24) );

   3.5、或者先通读,再按工程中要解决的问题来应用这些模式;(与上是同一段说的)

4、如果你对OO不是很熟的话,可以从几个最简单和通用的模式开始读,这些模式包括:

    * Abstract Factory (page 87)

    * Adapter (139)

    * Composite (163)

    * Decorator (175)

    * Factory Method (107)

    * Observer (293)

    * Strategy (315)

    * Template Method (325)

我暂时选择的阅读方式是上面的3.5的方式,先通读,并对比我在Thinking in Patterns with Java读到的相应的设计模式,以后如果写程序的话再按解决问题的分类“按图索骥”。

Thinking in Patterns chapter 19: Pattern refactoring

Thinking in Patterns with Java V0.9: chapter 19: Pattern refactoring:

TIPatterns.htm#_Toc41169793

1, Sections:

Pattern refactoring  181

Simulating the trash recycler. 182

Improving the design. 186

?Make more objects?. 186

A pattern for prototyping creation  189

Trash subclasses. 193

Parsing Trash from an external file  195

Recycling with prototyping. 198

Abstracting usage. 199

Multiple dispatching. 203

Implementing the double dispatch   204

The Visitor pattern. 211

A Reflective Decorator. 214

More coupling?. 219

RTTI considered harmful?. 220

Summary. 223

Exercises. 224

2, The main content and feeling:

This chapter foucuses on the applying of some patterns in the before chapters. With a trash recyleing system example, step by step, in an evoluting style, the book teachs me how to refine a system with design patterns by asking an important question in this processing: "what will change?" continuely.

The summary of this chapter is also the summary of design patterns given by the author. So, it worth to be read regularly later.

Here is some words about this summary:

1), "Design patterns in general strive to separate the things that change from the things that stay the same."

2), Finding the "vector of change" can be happened at any stage of a system's life. So, refining system may be happened through a system's life.

3), "What design patterns say is that OOP isn't just about polymorphism. It's about 'separating the things that change from the things that stay the same.'"

"But design patterns in general show other ways to accomplish the basic goal, and once your eyes have been opened to this you will begin to search for more creative designs."

4), Now, I make a review of how to refine a first-cut system step by step with design patterns in this book's trash recycling system.

(1), After the first-cut of "Simulating the trash recycler", the question to be raised:"What if the situation changes", for example, a new type trash called cardboard to be added into system, this will cause code less maintainable.

(2), So, "The solutions in Design Patterns are organized around the question

?What will change as this program evolves?? This is usually the most important

question that you can ask about any design. If you can build your system around

the answer, the results will be two-pronged: not only will your system allow

easy (and inexpensive) maintenance, but you might also produce components that

are reusable, so that other systems can be built more cheaply. "

"This brings up a general object-oriented design principle that I

first heard spoken by Grady Booch: 'If the design is too complicated, make more

objects.' "

Then a Messenger class to be created to encapsulate trash information, just the Messenger Pattern to be used here.

Then, the Factory Pattern to be used by "the only code that must be modified is within the factory, so the factory isolates the effect of that change."

 

For a more flexiable adding new trash type, the Prototype Pattern which hasn't been described in the previous chapters appears, it is just "The general idea is that you have a master sequence of objects, one of

each type you?re interested in making. The objects in this sequence are used

only for making new objects, using an operation that?s not unlike the clone( )

scheme built into Java?s root class Object. In this case, we?ll name the

cloning method tClone( ). When you?re ready to make a new object, presumably

you have some sort of information that establishes the type of object you want

to create, then you move through the master sequence comparing your information

with whatever appropriate information is in the prototype objects in the master

sequence. When you find one that matches your needs, you clone it."

But, in this example, the "master sequence of objects" doesn't hold "objects", they are Classes. And, with Java 1.1 reflection, these Class objects can be used to create the real object of that Class. Maybe, I have misunderstood "Prototype Pattern.

(3), But, "In terms of object creation, this design does indeed severely

localize the changes you need to make to add a new type to the system. However,

there?s a significant problem in the use of RTTI that shows up clearly here.

The program seems to run fine, and yet it never detects any cardboard, even

though there is cardboard in the list! This happens because of the use of RTTI,

which looks for only the types that you tell it to look for. The clue that RTTI

is being misused is that every type in the system is being tested, rather than

a single type or subset of types. As you will see later, there are ways to use

polymorphism instead when you?re testing for every type."

Because "RTTI is being misused", so we need step furthermore "So it?s worth trying to eliminate RTTI in this case, not just for aesthetic reasons?it produces more maintainable code."

(4), In the new implemetion of trash recyleing system: //: refactor:recycleb:RecycleB.java, "Adding new types to the system consists of adding or modifying distinct classes without causing code changes to be propagated throughout the system."

But, a further challenge be posted, RTTI "it should be eliminated altogether from the operation of sorting the trash into bins." I think to say it is because: "if(t.getClass().equals(type))" in the the code below:


  public boolean grab(Trash t) {

    // Comparing class types:

    if(t.getClass().equals(type)) {

      list.add(t);

      return true; // Object grabbed

    }

    return false; // Object not grabbed

  }

This code locates in //: refactor:recycleb:RecycleB.java.

Its meaning is "t.getClass()" is also a kind of RTTI? 

(5), So, the multiple dispatching to be used to "end up detecting some types manually and effectively producing your own dynamic

binding behavior" with "the polymorphism (dynamically-bound method calls) is to handle type-specific information for you."

Look at the code below, the multiple dispatching is used like this:

For trash:


interface TypedBinMember {

  // The new method:

  boolean addToBin(TypedBin[] tb);

} ///:~

For bin:


public abstract class TypedBin {

  Collection c = new ArrayList();

  protected boolean addIt(Trash t) {

    c.add(t);

    return true;

  }

  public Iterator iterator() {

    return c.iterator();

  }

  public boolean add(DDAluminum a) {

    return false;

  }

  public boolean add(DDPaper a) {

    return false;

  }

...

}

(6), "While previous versions of the trash sorting

example emphasized the addition of new types of Trash to the system,

TrashVisitor.java allows you to easily add new functionality without disturbing

the Trash hierarchy. There?s more code in TrashVisitor.java, but adding new

functionality to Visitor is cheap. If this is something that happens a lot,

then it?s worth the extra effort and code to make it happen more easily."

Here, the Vistor Pattern to be used for the reason above which be described in the summary of this chapter.

(7), Here, author tells me don't chase "Low coupling and high cohesion" too much :"Applied mindlessly, though, it can prevent you from achieving a more elegant design. It seems that some classes inevitably have a certain intimacy with each other. These often occur in pairs that could perhaps be called couplets;"

(8), At last, author tells me:"However, RTTI doesn?t automatically create non-extensible code. "

With right-use of "RTTI", //: refactor:dynatrash:DynaTrash.java

// Using a Map of Lists and RTTI to automatically sort

// trash into ArrayLists. This solution, despite the

// use of RTTI, is extensible.

And, it also is a beautiful design to use "a new tool will be introduced, which I call a TypeMap.", "This is certainly the smallest solution to the problem, and arguably the most elegant as well. It does rely heavily on RTTI,...".

It seems to tell me, with the good design, you can use almost any tool(technique) to build you system.

 

3, Questions about programming:

  1), return (Trash)ctor.newInstance(

            new Object[]{new Double(info.data)});

The process of calling

newInstance( ) extracts the double, but you can see it is a bit confusing?an

argument might be a double or a Double, but when you make the call you must

always pass in a Double. Fortunately, this issue exists only for the primitive

types.

  2),


public class Cardboard extends Trash {

  private static double val = 0.23f;

  public Cardboard(double wt) { super(wt); }

  public double getValue() { return val; }

  public static void setValue(double newVal) {

    val = newVal;

  }

} ///:~

A question: Can I put the code except constructor in such sub-class like above

into their super class: Trash and don't re-write them in all the sub-classes?

My researching:

Why don't do like below:


public abstract class Trash {

private double value;

private double weight;

public Trash(double val, double wt) {

value = val;

weight = wt;

}

public double getValue() {

return value;

}

public double getWeight() {

return weight;

}

}


public class Cardboard extends Trash {

  public Cardboard(double val, double wt) {

  super(val, wt);

  }

} ///:~

3),


//: refactor:doubledispatch:DDCardboard.java

// Cardboard for double dispatching.

package refactor.doubledispatch;

import refactor.trash.*;

 

public class DDCardboard extends Cardboard

    implements TypedBinMember {

  public DDCardboard(double wt) { super(wt); }

 

  public boolean addToBin(TypedBin[] tb) {

    for(int i = 0; i < tb.length; i++)

      if(tb[i].add(this))

        return true;

    return false;

  }

 

} ///:~

There is same code which be marked as red color in the above class as other classes like above, why don't put them into their base class?

There is an answer in the book:


But notice the argument: this. The type of this is different for each subclass of Trash, so the code is different.

But, I haven't understood very clearly, it needs more further learning for me.

4),

Of course, in this case it works well only if you’re adding new Visitors, but it gets in the way when you add new types of Trash.

4, Questions about english language:

1), Strange words:

 bin, Aluminum, branch off, silly, turn around, receptacle, enigma, commodity,

cardboard, definitely, recycling, appropriate, the results will be two-pronged,

promise, insight, refinement, would like, This is simultaneously counterintuitive and ludicrously simple, indirection, accidental, elevate, elaborate, eliminate, for that matter, presumably, work with, drop out, rectify, facilitate, severely, aesthetic, clue, be aware of,strictly,satisfactory, purist, altogether, dilemma, have control of, ease, Reflective, albeit, tally, inevitable, intimacy, in pairs, couplets, condemnation, ill-fated, stated, counterproductive, strive, analyst, about-face, syndrome, prohibitively, fame, proponent, autonomous,

2), Strange sentences:

 

 The extra constraint is that the trash arrives at the trash recycling plant all mixed together.

 (Indeed, this is the whole enigma of recycling).

(we?ve started referring to Messenger as a design pattern, but it?s simple enough that you may not choose to elevate it to that status).

then you move through the master sequence comparing your information with whatever appropriate information is in the prototype objects in the master sequence.(whatever?)

If it still can?t be found something is really wrong, but if

the load is successful then the factory method is called recursively to try

again.

Note that the benefit is helpful here but not exactly what we started out to accomplish, so at first blush you might decide that this isn’t the desired solution.

   incomplete

UML建模中的状态图及状态图建模原则示例摘要(转摘)

在学习Thinking in Patterns chapter 18: Complex system states中的StateMachine的前半部分时(TIPatterns.htm#_Toc41169779),与我原来看那本System Analysis and Design中文译本中的UML建模中的状态图作了一下比较。发现二者有比较大的区别,故把状态图的有关知识再复习了一下。

下面是我在网上搜索到的一篇讲述UML状态图的文章,其中对状态图的基本定义和它在实际应用中的示例和原则都作了详细的阐述。不过比较长,而且是翻译过来的,很不好理解。尤其是前半部分讲基础概念的,更是模模糊糊的。我根据自己的需要,把上面的内容摘录了一些提纲性的东西备用。

一、基础部分

  状态图(Statechart Diagram)是描述一个实体基于事件反应的动态行为,显示了该实体如何根据当前所处的状态对不同的时间做出反应的。通常我们创建一个UML状态图是为了以下的研究目的:研究类、角色、子系统、或组件的复杂行为。

 

  状态机由状态组成,各状态由转移链接在一起。状态是对象执行某项活动或等待某个事件时的条件。转移是两个状态之间的关系,它由某个事件触发,然后执行特定的操作或评估并导致特定的结束状态。图 1 描绘了状态机的各种元素。

  状态机的要素:(图 1:状态机符号。)

  状态的要素:


名称:            将一个状态与其他状态区分开来的文本字符串;状态也可能是匿名的,这表示它没有名称。

进入/退出操作:    在进入和退出状态时所执行的操作。

内部转移:        在不使状态发生变更的情况下进行的转移。

子状态:          状态的嵌套结构,包括不相连的(依次处于活动状态的)或并行的(同时处于活动状态的)子状态。

延迟的事件:      未在该状态中处理但被延迟处理(即列队等待由另一个状态中的对象来处理)的一系列事件。

  转移的要素:


源状态:            转移所影响的状态;如果对象处于源状态,当对象收到转移的触发事件并且满足警戒条件(如果有)时,就可能会触发输出转移。

事件触发器:        使转移满足触发条件的事件。当处于源状态的对象收到该事件时(假设已满足其警戒条件),就可能会触发转移。

警戒条件:          一种布尔表达式。在接收到事件触发器而触发转移时,将对该表达式求值;如果该表达式求值结果为 True,则说明转移符合触发条件;如果该表达式求值结果为 False,则不触发转移。如果没有其他转移可以由同一事件来触发,该事件就将被丢弃。

操作:              可执行的、不可分割的计算过程,该计算可能直接作用于拥有状态机的对象,也可能间接作用于该对象可见的其他对象。

目标状态:          在完成转移后被激活的状态。

二、应用示例部分(结合示例讲了画状态图的一些准则):

  我觉得文中的这个示例太好了,值得经常看看。

1、通用准则

  1.1)、当行为的改变和状态有关时才创建状态图

  敏捷建模( AM) ( Ambler 2002)的原则--最大化项目干系人的投资--建议你只有当模型能够提供正面价值的时候才创建模型。

   

图⒈班级注册的一个UML状态图。

  1.2)、把初始状态放置在左上角。

  1.3)、把最终状态放置在右下角。

2、状态指南

  状态是一个实体的行为模式的某个阶段。 状态的表示是通过实体的属性值。

  2.1)、状态名称要简单但应具有描述性。

  2.2)、避免"黑洞"状态。

  2.3)、避免"奇迹"状态。

3、子状态建模指南

  3.1)、为复杂的目标建模子状态。

图⒉Seminar的完整生命周期

  3.2)、把通用的子状态变换放在一起

  3.3)、为复杂的实体创建一个分层的状态图

图⒊Seminar的高阶状态图。

  3.4)、最高阶的状态图总有初始态和最终态

4、变换和动作

  变换是从一种状态到另一种状态的序列,它可能是通过一个事件触发的。

  4.1)、用实现语言的命名规则命名软件动作

  4.2)、只有对所有的入口变换都合适时才注明入口动作

  4.3)、只有对所有的出口变换适合时才注明出口动作

  4.4)、出口动作,用exit/标记来表示,工作方式类似于入口动作。

  4.5)、只有当你想终止并再进入该状态时才建模递归变换

  4.6)、用过去式命名转换事件

  4.7)、把转换标记放在接近源状态的地方

  4.8)、以转换方向为基础放置变换标记

    4.9)、为了更易于判断哪个标记和变换是一起的,按照如下的规则来放置变换标记:

      4.9.1)、在变换线条上的从左到右。

      4.9.2)、在变换线条下的从右到左。

      4.9.3)、变换线条右边的往下。

      4.9.4)、变换线条左边的往上。

5、警戒点

  一个警戒点是为了穿过一个转换而必须为真的一个条件。

  5.1)、警戒点不应该重叠

  5.2)、为可视化的定位警戒点而引入接合点。

  5.3)、警戒点不必配套

  5.4)、一致的命名警戒点

××××××××××××××××××××××××××××××××××××××××××××××××××××××××××

                          摘录完毕

Thinking in Patterns chapter 18: Complex system states

Thinking in Patterns with Java V0.9: chapter 18: Complex system states: TIPatterns.htm#_Toc41169778

1, Sections:

Complex system states  159

  StateMachine. 159

    Exercises. 169

  Table-Driven State Machine. 169

    The State class. 171

    Conditions for transition. 172

    Transition actions. 172

    The table. 172

    The basic machine. 173

    Simple vending machine. 174

    Testing the machine. 179

  Tools. 180

  Table-driven code: configuration flexibility  180

    Table-driven code using anonymous inner classes  180

  Exercises. 180

2, The main content and feeling:

 

  Although I have been stopped at this chapter and State chart Diagram in UML

two or three days, there are still some questions left. But, I can't stay here

too long, there are many need to read, so, left some questions here, maybe

they will be resolved in the "future".

First of all, I found there isn't a pattern called "StateMachine Pattern" in

GoF's book except a pattern called "state pattern". Maybe, this is a design pattern invented by Bruce, just like the words below:


This method not only moves to the next state, but it also calls run( ) for each state object ? thus you can see it?s an expansion of the idea of the State pattern, since run( ) does something different depending on the state that the system is in.

What is Bruce's "StateMachine Pattern"?

He tells us:


While State has a way to allow the client programmer to change the

implementation, StateMachine imposes a structure to automatically change the

implementation from one object to the next.

There are two types of "StateMachine Pattern" implementation in this book.

The first is called "StateMachine" simplily, and second is called "Table-Driven State Machine". When I read these two "statemachine", I compared them with the State chart Diagram in UML I have learned before. So I found some question I can't answer. Below is my understanding for these two Bruce's StateMachine.

At first, give my understanding about State chart Diagram in UML, I like its

OOP style, even I maybe missunderstood it, I put my understanding here, wish

someone can point out my error.

A State chart Diagram can be owned by an entity(for example, an object of a

class ), if the entity's action dependents on what state the entity is in, then a state chart diagram may be needed.

For me, the most important understanding about this is the transition between

two states. Three things can be in a transition: event, just a call to this

object's method or a message send to this object; guard condition, only it is

"true" can event cause a state's change; action, just some processes in

object's method or some messages send to other objects to perform somethings during this transition.

Then, bring the idea of UML's state chart diagram in my mind, I look at Bruce's first "StateMachine".

In this statemachine, all is focus on the state class. state class performace

some actions in the transition SHOULD before this state, state class recieve an input

and decide which state is the next state.

Just like below:


public interface State {

  void run();

  State next(Input i);

} ///:~

Why do I say "state class performace some actions in the transition SHOULD before this state"?

Because I read some in this book like below:


 and as that transition is made some kind of action occurs (in the previous state machine design, this was the run( ) method):

I try to model the example of "statemachine" with UML's state chart diagram,

but I failed. Because the state object has done all the things, and the owner of

state objects has nothing to do. I can't send the owner a message which should

be a method of the owner to make a transition!

And another question in the example is:


class Waiting implements State {

  public void run() {

    System.out.println(

      "Waiting: Broadcasting cheese smell");

  }

  public State next(Input i) {

    MouseAction ma = (MouseAction)i;

    if(ma.equals(MouseAction.appears))

      return MouseTrap.luring;

    return MouseTrap.waiting;

  }

}

Why is "Waiting: Broadcasting cheese smell" in the run() method, but not

"Wait: Broadcast cheese smell"? Does it indicate a state or an action during transition before this state? I am a little confusing.

And, from the State chart diagram's definition, an action should be occured

before current state appeared in this example, but I don't know why it happens

as a run() method in a state object, just like below:


  public final void runAll(Iterator inputs) {

    while(inputs.hasNext()) {

      Input i = (Input)inputs.next();

      System.out.println(i);

      currentState = currentState.next(i);

      currentState.run();

    }

Next, from section "Table-Driven State Machine" I can draw example's State

chart Diagram using UML tool.

In this example, the state class can't do something like above's example, and,

an object called stateMachine holds every thing. I can send this stateMachine

a message: nextState(input: Input), this just a event cause the state's

change; And, when this transition is made, an action occurs by nextState()

to call another object's method: Transition.transition(input: Input), or the

stateMachine object just send a message to trasition object to do some actions.

Maybe, this just is the meaning of Bruce's words: "The classic state-transition diagram".

Maybe, Bruce's statemachine is from the aspect of using purpose, all these examples are focusing on how to design a statemachine conveniently; But I focus on if these "statemachine" are real "StateMachine" defined in UML.

Maybe, I have misunderstood all the UML's "statemachine" and the

"statemachine" in this book's example. If any of these case, please give me a

hint. My english is also very poor, if there are some thing unclear, please

let ne know. Thanks.

3, Questions about programming:

Many questions has been written above. Except above, There are entire section

I can't understand just below:


(Simple State Machine Diagram)

Goals:

·         Direct translation of state diagram

·         Vector of change: the state diagram representation

·         Reasonable implementation

·         No excess of states (you could represent every single change with a new state)

·         Simplicity and flexibility

Observations:

·         States are trivial – no information or functions/data, just an identity

·         Not like the State pattern!

·         The machine governs the move from state to state

·         Similar to flyweight

·         Each state may move to many others

·         Condition & action functions must also be external to states

·         Centralize description in a single table containing all variations, for ease of configuration

Example:

·         State Machine & Table-Driven Code

·         Implements a vending machine

·         Uses several other patterns

·         Separates common state-machine code from specific application (like template method)

·         Each input causes a seek for appropriate solution (like chain of responsibility)

·         Tests and transitions are encapsulated in function objects (objects that hold functions)

·         Java constraint: methods are not first-class objects

And, I almost can't see the picture after this section.

4, Questions about english language:

1), Strange words:

  impose, tagging, conceivably, mousetrap, theWhiW,

2), Strange sentences:

 // A State has an operation, and can be moved

 // into the next State given an Input:

This is typical, but certainly not required ? you could concievably want to override it, but typically the behavior change will occur in State?s run( ) instead.

   incomplete

Thinking in Patterns chapter 17: Multiple languages

Thinking in Patterns with Java V0.9: chapter 17: Multiple languages: TIPatterns.htm#_Toc41169757

1, Sections:

Multiple languages  120

  Interpreter motivation. 121

  Python overview.. 122

    Built-in containers. 123

    Functions. 124

    Strings. 125

    Classes. 127

  Creating a language. 130

  Controlling the interpreter. 134

    Putting data in. 134

    Getting data out. 140

    Multiple interpreters. 143

  Controlling Java from Jython  144

    Inner Classes. 148

  Using Java libraries. 148

    Inheriting from Java library classes  150

  Creating Java classes with Jython  151

    Building the Java classes from the Python code  156

  The Java-Python Extension (JPE)  157

  Summary. 157

  Exercises

2, The main content and feeling:

  First at all, let me remember a fact, this book is written at 3 years ago,

too many changes has been taken, so I think the language Python introduced

by Bruce in this book has many changes. And, there are many kinds of other languages maybe has present.

  Then, let us see what has been told in this chapter.

  At last, two days' reading without installing Python or Jython, I get a

conclusion: Python, maybe is the best lovely program language of Bruce's. The

most part of this chapter is introducing Python. On the other hand, the Interpreter Pattern in this Design patterns book is a little part of this chapter.

 

  What is Interpreter Pattern?

  It says:

 


  Sometimes the end users of your application (rather than the programmers of

that application) need complete flexibility in the way that they configure

some aspect of the program. That is, they need to do some kind of simple

programming. The interpreter pattern provides this flexibility by adding a

language interpreter.

 

  Note, although in almost all applications there are some factors that end

user can change it by some ways, for example, input something or press some

buttons, etc.. But, in a interpreter pattern, it provides end users the most probability for custom there many factors by simple programming.

  And, a ready for use this kind of Interpreter system introduced by Bruce is

Jython, a pure Java implementation of Python language. Of course, you can

write your own Interpreter sytem. But it seems too unecessary.

  Along with Bruce's lines, I got some about Python and Jython, and this is

almost real the first touch of this language for me. I can understand little

 bit of examples in this book without to run it under *ython.

  Use some sentences in this book to summary the understanding for *ython of

mine.

 


Python is a language that is very easy to learn, very logical to read

and write, supports functions and objects, has a large set of available

libraries, and runs on virtually every platform.

 

 


 It is marvelous for scripting, and you may find yourself

replacing all your batch files, shell scripts, and simple programs with Python

scripts. But it is far more than a scripting language.

 

 ...

 If you program with *ython, no redundant charactor typing. And it can be

worked together with java very well. All the Jython class and Java class can

almost interact without any problem. And, if you need native Python program

interact with Java, a resolution called The Java-Python Extension (JPE) can be

used.

  In this book, Bruce says maybe a new Design Pattern called Multiple Language

can be invented. In this way, mixing languages to resolve a question can be

better than using only one language. All the languages has its advantage and

shortage, mix them is a good idea.

  Bruce says:

 


  To me, Python and Java present a very potent combination for program

development because of Java?s architecture and tool set, and Python?s

extremely rapid development (generally considered to be 5-10 times faster than C++ or Java).

 

  But, I doubt that "5-10 times faster than C++ or Java", although I am not a

professional programmer(I don't work in IT), I think it is impossible that a

language has 5-10 times development speed than others. Because, building an

application need not only coding, but also many other works. I suppose, Python is good at coding, at building a good classes system, but, what classes are we need? How do they interact with each other? etc.. These kind of things is can't be reduced many only by a language.

 But, maybe, "Python?s extremely rapid development" is only refer to coding,

and mix this coding process with "Java's architecture" which is good at

building system architecture.

3, Questions about programming:

  1), if you create fields using the C++/Java style, they implicitly become static fields.

  2),

In addition, Jython’s JavaBean awareness means that a call to any method with a name that begins with “set” can be replaced with an assignment, as you can see above.

You are not required to inherit from Object; any other Java class will do.

Note that it?s important that the directory where the target lives be specified, so that the makefile will create the Java program with the minimum necessary amount of rebuilding.

4, Questions about english language:

1), Strange words:

 advantageous, arbitrarily, stuck, tedious, Interpreter, distraction, for-profit, royalties, basically, incorporating, scales up, purity, referred to, marvelous, affirmative, subsequent, add-on, acknowledged, associative, formalize, takes on, imitate, verbiage, signature, other than, tuple, control over, decimal place, spare, set off,  turns out to be,  aggressively, albeit, penchant, comma, from within, deceptively, thorough, further down, ambiguous, back and forth, it is worth noting that, disposal, endearing, intuitively, awareness, automated, shorthand, presumably,

come over, lambda, succinct, hood, frustrating, stem from, arguably, lurking,

potent, flesh out, terrific, leverage

2), Strange sentences:

 Indenting can nest to any level, just like curly braces in C++ or Java, but unlike those languages there is no option (and no argument) about where the braces are placed  the compiler forces everyone’s code to be formatted the same way, which is one of the main reasons for Python’s consistent readability.

 Note that Python was not named after the snake, but rather the Monty Python comedy troupe, and so examples are virtually required to include Python-esque references.

   incomplete

Thinking in Patterns Chapter 16: Complex interactions

Thinking in Patterns with Java V0.9: Chapter 16: Complex interactions: TIPatterns.htm#_Toc41169753

 1, Sections:

Externalizing object state  113

  Memento. 113

Complex interactions  114

  Multiple dispatching. 114

  Visitor, a type of multiple dispatching  117

  Exercises

2, The main content and feeling:

  Memento Pattern isn't described in this book(So I don't write a diary of Chapter 16: Externalizing object state), I must learn it in other place.

 

  After twice reading of chapter: Complex interactions, I got little from the book. Don't like Thinking in Java, in that book, there is detail explaination after every example. But, it isn't given explaination in this chapter's two examples. This book is only Version0.9.

  1), What is Multiple dispatching? I knew it from this point: "Remember that polymorphism can occur only via member function calls, if you want double dispatching to occur, there must be two member function calls: the first to determine the first unknown type, and the second to determine the second unknown type." 

  Just describe it use the example in the book below:


class Scissors implements Item {

  public Outcome compete(Item it) { return it.eval(this); }

  public Outcome eval(Paper p) { return Outcome.LOSE; }

  // ...

}


class Paper implements Item {

  public Outcome compete(Item it) { return it.eval(this); }

  public Outcome eval(Paper p) { return Outcome.DRAW; }

  //..

}

  Here, a scissors vs. a paper:

  s Item = new Scissors();

  p Item = new Paper();

  s.compete(p); // the first(method compete()) to determine the first unknown type(Scissors),

 

  //In the method "compete()", the second method is called

  p.eval(s);// the second(method eval()) to determine the second unknown type(Paper),

  Why does the first(method compete()) NOT to determine the second unknown type(Paper)?

  The key is this statement above:

  polymorphism can occur only via member function calls

  When the method compete() be called, the type of the object that call this method is determined, "Item" "s" is a "Scissors".

  The second method eval() is same as the first method complete().

  2), Visitor, a type of multiple dispatching

 

  After know the Mutiple dispatching, Vistor Pattern is understood soon. Because, it "builds on the double dispatching scheme shown in the last section".

  There is a point need to note, the purpose of using Vistor Patterns is changing the method's behavior without modifying original hierarchy.

  I explain this using the example in the book too:

  In this example, Flower classes hierarchy can't be changed. And can determining it's type by calling it's method: accept(Visitor v);

 

  Although Flower classes herarchy can't be changed, but Visitor classes herarchy can be changed, so there are two types of Visitor be created, one is "StringVal", another is "Bee". And, the second Type be determined in this method below:

  v.visit(this); //"this" is a Flower, when the "v" call visit() method, its type be termined. And, different type Vistor visit(this) can get different behavior, that just we want to get.

  3), Multiple dispatching can be replaced by a table lookup, just look it in the exercise 3.

  I think there are two type of Map will be used. it is one: key is class, value is another map; another map: key is class, value is outcome.

  4), At this point, I suddenly think, I guess, Bruce thinks the Design Pattern isn't a very import thing in his software design, I feel his words outside this book is just saying: many of these "Dsign Patterns" is redundant, a basic idea of mine be divided into these too many Patterns, this basic idea is: No pattern is patterns for all.

  This is only my guess, my feeling. If my feeling is right, maybe, we maybe can't see a version1.0 of this book:(

  My english language and program knowledge is poor, if I make any mistake, please tell me: mdx-xx@tom.com

 

3, Questions about programming:

  1), The answer starts with something you probably don’t think about: Java performs only single dispatching. That is, if you are performing an operation on more than one object whose type is unknown, Java can invoke the dynamic binding mechanism on only one of those types. This doesn’t solve the problem, so you end up detecting some types manually and effectively producing your own dynamic binding behavior.

  2), How to do if there are more than double dispatching in the above?

  Like below?

  a.F(b);

  b.G(c);

  c.H(a);

  ...

  3), All the exercises.

 

4, Questions about english language:

1), Strange words:

 compete, Scissors, Outcome, primary, dilemma, virtualize, bound, Gladiolus, Runuculus, Chrysanthemum, Inhabitant, Dwarf, Elf, Troll, Jargon, InventFeature,

Each Inhabitant can randomly produce a Weapon using getWeapon( ): a Dwarf uses Jargon or Play, an Elf uses InventFeature or SellImaginaryProduct, and a Troll uses Edict and Schedule.

syntactic, simplicity,

2), Difficult sentences:

The easiest way to do this is to create a Map of Maps, with the key of each Map the class of each object.

 

******************************************************************

The class diagrams of two examples in the book:

1),//: multipledispatch:PaperScissorsRock.java

2),//: visitor:BeeAndFlowers.java



 

    incomplete

Thinking in Patterns Chapter 14: Algorithmic partitioning

Thinking in Patterns with Java V0.9: Chapter 14: Algorithmic partitioning: TIPatterns.htm#_Toc41169746

1, Sections:

Algorithmic partitioning  106

  Command: choosing the operation at run-time  106

    Exercises. 109

  Chain of responsibility. 109

    Exercises

2, The main content and feeling:

  1) Command pattern:

  It is "wrapping a method in an object". From my understanding, a Command is a very simple class with a sole method to resolve a specific task. When I perform a big task, I can put some of these Command objects together, and in a "manager" class, call these object's own sole method to perform its specific little task, and, in this way, to finish that big task through these little object's contributions.

 

  In my first touch of these patterns, I think there are clear differents between Command Pattern and Strategy Pattern:

  Command Pattern: Put serveral Command objects together to perform a common task, just like draw together to fight on a common enemy;

  Strategy Pattern: At a specific time use a specific Strategy to accomplish a different result.

  But, why does Bruce say below in the book:

 


 I would hazard to say that Command provides flexibility while you’re writing the program, whereas Strategy’s flexibility is at run time. Nonetheless, it seems a rather fragile distinction.

 

 

  Maybe, Bruce describe it from the structural aspect, I look at them at the function's aspect.

  

  2) Chain of Responsibility:

  That just an "Expert System", there are several experts in this system, and, these experts wait here in line. When a problem come, from the first expert to the last expert, every expert try to resolve this problem. If one can't do it, then the problem be handed to the next expert, until the problem be rosolved or the last expert can't do it yet, then an un-resolved problem is retruned.

  From this view aspect, Chain of Responsibility just like an auto-selected Strategy Pattern: the method for resolving problem is auto selected in the former, and a manual-selected strategy used for a problem in the later.

  A question raises, what if the problem handed to the Expert System need serveral experts to resolve them respectively? Maybe, this problem need to be cuted into serveral little problems then hand them into the expert system successively.

  In this pattern, Bruce says GoF use many words to create an linked list to contain these "experts", it is because GoF wrote that Design Pattern at the time "before the Standard Template Library (STL) was incorporated into most C++ compilers'. But, in Java, a ready-made List is here.

  In fact, I need review these content when I finish the first reading of this book. So, although there are some place I can't understand it very clearly, but, I must go on, finish the first reading of entire book in shortest time is the most import thing. I just only read half of this book. After reading this book once, the J2EE Design Patterns need me to read. So, don't tie at any specific point, go! go! go!

3, Questions about programming:

  1), The point is to decouple the choice of function to be called from the site where that function is called.

  2),  something you can normally only do by writing new code but in the above example could be done by interpreting a script.

  3), What is the famous "callback" technique?

4, Questions about english language:

1), Strange words:

   functor, collectively, incorporated into, BabelFish, Bisection, ConjugateGradient, fragile

2), Difficult sentences:

On the other hand, with a Command object you typically just create it and hand it to some method or object, and are not otherwise connected over time to the Command object.

 

********************************************************************************************************

Class diagram of //: chainofresponsibility:FindMinima.java in section: Chain of responsibility

                                     incomplete