积木

No sub title

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  140 Posts :: 1 Stories :: 11 Comments :: 0 Trackbacks

常用链接

留言簿(1)

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜

#

转载自:http://blog.csdn.net/sky04/article/details/6536011

要防止因为异常产生的内存泄漏,可以使用智能指针,也可以用
__try
{
}
__finally
{
}
《Windows核心编程》一书第23~25章是很好的参考资料。

----------------------------------------------------

try,catch,throw:

try包含你要防护的代码,称为防护块. 防护块如果出现异常,会自动生成异常对象并抛出.

catch捕捉特定的异常,并在其中进行适当处理.

throw可以直接抛出/产生异常,导致控制流程转到catch块.

重要观点: C++中异常是用对象来表示的,称为异常对象.


基本格式:

try { your code; }

catch(T1 t1) //T1可以是任意类型,int,char, CException...

{ /*T1指定了你要捕捉的异常的类型,t1指定了异常 对象的名称,当有异常抛出,异常对象将被复制到t1 中,这样你就可以在本处理块中使用该对象,获取相关 信息,进行适当处理. 处理代码;*/}

catch(T2* pt1)

//上面的catch是值传递,这里使用指针传递.

{ 处理代码; }

catch(...)

//...是捕捉任意类型的异常.

{ 处理代码; }

//其他代码;

/*某个catch执行完,就跳转到这里继续执行. 在没有使用C++异常处理的情况下,如果在 此之前出现异常,则//这里的其他代码不会被执行 从而造成问题.请考虑在这里放置: delete pobj1; 如果不使用用try,catch机制,内存泄漏是必然的, 因为出现问题后,执行流程无法跳转到这里. */


/*说明: try{}之后可以跟任意个catch块. 发生异常后,会生成临时的异常对象,进行一些自动处理之后,程序流程跳转到后面的catch(),逐个检查这些catch(),如果与catch() 中指定的类型一致,则将对象拷贝给catch参数中的对象, 接着执行该catch块中的代码,然后跳过其他所有剩下的catch, 继续执行后续的代码.
上面所说的自动处理指的是堆栈回退,说白了就是为函数中的局部对象调用析构函数,保证这些局部对象行为良好. */


catch()的顺序通常按照:从特殊到一般的顺序: catch(Tsub o){} catch(Tbase o){} catch(...){} 如果第一个catch为catch(Tbase){},则它将捕捉其所有派生类的 异常对象. 如果第一个catch为catch(...){},则其后的所有catch永远不可能 被执行.
重新抛出异常: 从上面的处理机制可以看到,只有一个catch可能被执行, 如果一个catch被执行,其他后续的catch就会被跳过了. 有时候一个catch中可能无法完成异常的全部处理,需要将 异常提交给更高的层,以期望得到处理.重新抛出异常实现 了这种可能性. 语法: throw ; 空的throw语句,只能在catch中使用. 它重新抛出异常对象,其外层的catch可能可以捕捉这个重新抛出的异常并做适当处理.

---------------------------------------------------------------------------------------------------------

1、基础介绍
try
{
//程序中抛出异常
throw value;
}
catch(valuetype v)
{
//例外处理程序段
}
语法小结:throw抛出值,catch接受,当然,throw必须在“try语句块”中才有效。

2、深入throw:
(i)、程序接受到throw语句后就会自动调用析构器,把该域(try后的括号内)对象clean up,然后再进
入catch语句(如果在循环体中就退出循环)。

这种机制会引起一些致命的错误,比如,当“类”有指针成员变量时(又是指针!),在 “类的构建器
”中的throw语句引起的退出,会导致这个指针所指向的对象没有被析构。这里很基础,就不深入了,提
示一下,把指针改为类就行了,比如模板类来代替指针,在模板类的内部设置一个析构函数。

(ii)、语句“throw;”抛出一个无法被捕获的异常,即使是catch(...)也不能捕捉到,这时进入终止函数
,见下catch。

3、深入catch:
一般的catch出现的形式是:
try{}
catch(except1&){}
catch(except2&){}
catch(...){} //接受所有异常
一般都写成引用(except1&),原因很简单,效率。

问题a:抛出异常,但是catch不到异常怎么办?(注意没有java类似的finally语句)
在catch没有捕获到匹配的异常的时候,会调用默认的终止函数。可以调用set_terminate()来设置终止函数,参数是一个函数指针,类型是:void (*terminate)()。

到这里,可以题个问题:“没有try-catch,直接在程序中"throw;",会怎么样?”


其他一些技巧:
4、try一个函数体,形式如下
void fun(type1,type2) try----try放在函数体后
{
函数定义
}
catch(typeX){}
这个用法的效果就相当于:
void fun()
{
try{函数定义}
}


5、throw一个函数体,形式如下:
void fun (); // 能抛出任何类型的异常
void fun () throw(except1,except2,except3)
// 后面括号里面是一个异常参数表,本例中只能抛出这3中异常
void fun () throw() // 参数表为空,不能抛出异常

问题b:假设fun()中抛出了一个不在“异常参数表”中的异常,会怎么样?

答:调用set_terminate()中设定的终止函数。然而,这只是表面现象,实际上是调用默认的unexpected()函数,然而这个默认的 unexpected()调用了set_terminate()中设定的终止函数。可以用set_unexpected()来设置unexpected, 就像set_terminate()一样的用法,但是在设定了新的“unexpected()”之后,就不会再调用set_terminater中设定的 终止函数了。

这个语法是很有用的,因为在用别人的代码时,不知道哪个地方会调用什么函数又会抛出什么异常,用一个异常参数表在申明时限制一下,很实用。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

try{} catch(…){}

以前都是用try{} catch(…){}来捕获C++中一些意想不到的异常,今天看了Winhack的帖子才知道,这种方法在VC中其实是靠不住的。例如下面的代码:

  1. try
  2. {
  3. BYTE*pch;
  4. pch=( BYTE*)00001234; // 给予一个非法地址
  5. *pch=6;// 对非法地址赋值,会造成Access Violation 异常
  6. }
  7. catch(...)
  8. {
  9. AfxMessageBox( "catched");
  10. }

这段代码在debug下没有问题,异常会被捕获,会弹出”catched”的消息框。但在Release方式下如果选择了编译器代码优化选项,则VC编译器会去搜索try块中的代码, 如果没有找到throw代码,他就会认为try catch结构是多余的, 给优化掉。这样造成在Release模式下,上述代码中的异常不能被捕获,从而迫使程序弹出错误提示框退出。

那么能否在release代码优化状态下捕获这个异常呢, 答案是有的。 就是__try, __except结构,上述代码如果改成如下代码异常即可捕获。

  1. __try
  2. {
  3. BYTE*pch;
  4. pch=( BYTE*)00001234; // 给予一个非法地址
  5. *pch=6;// 对非法地址赋值,会造成Access Violation 异常
  6. }
  7. __except( EXCEPTION_EXECUTE_HANDLER)
  8. {
  9. AfxMessageBox( "catched");
  10. }

但是用__try, __except块还有问题, 就是这个不是C++标准, 而是Windows平台特有的扩展。而且如果在使用过程中涉及局部对象析构函数的调用,则会出现C2712的编译错误。 那么还有没有别的办法呢?

当然有, 就是仍然使用C++标准的try{}catch(..){}, 但在编译命令行中加入 /EHa的参数。这样VC编译器不会把try catch模块给优化掉了。

一篇比较好的英文文章谈这个问题: http://members.cox.net/doug_web/eh.htm


posted @ 2013-03-11 16:51 Jacc.Kim 阅读(1065) | 评论 (0)编辑 收藏

转载自:http://blog.linguofeng.com/archive/2012/09/12/cocos2d-x-touch.html

一、两种机制的四种不同的事件

CCStandardTouchDelegate 默认事件
virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent); 处理按下事件
virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent); 处理按下并移动事件
virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent); 处理松开事件
virtual void ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent); 处理打断事件
CCTargetedTouchDelegate
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent); 处理用户按下事件,true表示继续处理, 否则false.
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent); 处理按下并移动事件
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); 处理松开事件
virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent); 处理打断事件

两者的区别: CCSetCCTouch ,一个事件集合一个单个事件。

事件分发的顺序: CCTargetedTouchDelegateCCStandardTouchDelegate

默认情况下所有 CCLayer 都没有启用触摸事件,需要 this->setIsTouchEnabled(true); 启用。

如需更改事件: void registerWithTouchDispatcher(void) {}

class MyLayer: public cocos2d:CCLayer {
public:
    virtual void registerWithTouchDispatcher(void);

    // addStandardDelegate()
    virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);
    virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent);
    virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent);
    virtual void ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent);

    // addTargetedDelegate()
    virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
    virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
    virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
    virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);
}

void MyLayer::registerWithTouchDispatcher(void) {
    // 委托,优先级
    CCTouchDispatcher::sharedDispatcher()->addStandardDelegate(this, kCCMenuTouchPriority);
    // 委托,优先级,是否继续处理
    CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, kCCMenuTouchPriority, true);

    // 2.0版本以后
    CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this, kCCMenuHandlerPriority);
    CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, kCCMenuHandlerPriority, true);
}

利用 ccTouchBeganccTouchesBegan 加以实现点击的回调

void MyLayer::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent) {
    // 单点
    CCTouch *pTouch = (CCTouch*)(pTouches->anyObject());

    // 所有点
    for(CCSetIterator iterTouch = pTouches->begin(); iterTouch != pTouches->end(); iterTouch++) {
        CCTouch *pCurTouch =  (CCTouch*)(*iterTouch);
    }

    // 获取点在视图中的坐标(左上角为原点)
    CCPoint touchLocation = pTouch->getLocationInView();
    // 把点的坐标转换成OpenGL坐标(左下角为原点)
    touchLocation = CCDirector::sharedDirector()->convertToGL(touchLocation);
    // 把OpenGL的坐标转换成CCLayer的坐标
    CCPoint local = convertToNodeSpace(touchLocation)
    // 大小为100x100,坐标为(0, 0)的矩形
    CCRect * rect = CCRectMake(0, 0, 100, 100);
    // 判断该坐标是否在rect矩形内
    bool flag = rect.containsPoint(local)
    if(flag) {
        // 回调
    } else {
        // 不执行
    }
}


posted @ 2013-03-10 00:28 Jacc.Kim 阅读(5876) | 评论 (0)编辑 收藏

     摘要: 转载自:http://patmusing.blog.163.com/blog/static/1358349602010150249596/ 表示一个作用于某对象结构中的各元素的操作。它可以在不改变各元素的类的前提下定义作用于这些元素的新的操作。 “Represent an operation to be performed on the elements of an object ...  阅读全文
posted @ 2013-03-08 16:01 Jacc.Kim 阅读(242) | 评论 (0)编辑 收藏

转载自:http://patmusing.blog.163.com/blog/static/1358349602010150231168/

在一个方法中定义一个算法的框架,并将该算法的某些步骤,延迟到子类实现。Template Method使得子类可以重新定义一个算法中的某些特定的步骤,而无需改变整个算法的结构。

“Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.” - GoF

换言之,Template Method提供一个方法,以允许子类重写该方法的一部分,而无需重写整个子类。

比如,对于某一项任务,如果它有一个复杂的成员函数,并且该成员函数可以分成几个步骤,同时这几个步骤构成成员函数的整体结构式稳定的,但各个子步骤却有很多改变的需求,这样的情形下就特别适合使用Template MethodTemplate Method设计模式就是在确定稳定的成员函数组成结构的前提下,应对各个子步骤的变化。

Template Method模式之UML类图:

25. C++实现Behavioral - Template Method模式 - 玄机逸士 - 玄机逸士博客

业务示例:

测试各种不同的小汽车。

//TemplateMethod.h

#include <iostream>

using namespace std;

class TestVehicle

{

public:

void test() // 测试。这就是Template Method。它一共由6个步骤按照一定的时间

{ // 顺序组成,但各个步骤的实现被延迟到TestVehicle的子类

cout << "Start to test...." << endl; // 模拟固定部分的代码

start_up(); // 启动

blow_horn(); // 按喇叭

run(); // 行驶

turn(); // 转弯

brake(); // 刹车

stop(); // 停车

cout << "Test finished..." << endl; // 模拟固定部分的代码

}

virtual ~TestVehicle()

{

cout << "in the destructor of TestVehicle..." << endl;

}

protected:

virtual void start_up() = 0;

virtual void blow_horn() = 0;

virtual void run() = 0;

virtual void turn() = 0;

virtual void brake() = 0;

virtual void stop() = 0;

};

// 测试帕沙特

class TestPassat : public TestVehicle

{

public:

~TestPassat()

{

cout << "in the destructor of TestPassat..." << endl;

}

protected:

void start_up()

{

cout << "--- Passat:\tstart up ---" << endl; // 模拟启动Passat

}

void blow_horn()

{

cout << "--- Passat:\tblow the horn ---" << endl; // 模拟按Passat的喇叭

}

void run()

{

cout << "--- Passat:\trun ---" << endl; // 模拟Passat行驶

}

void turn()

{

cout << "--- Passat:\ttrun ---" << endl; // 模拟Passat转弯

}

void brake()

{

cout << "--- Passat:\tbrake ---" << endl; // 模拟Passat刹车

}

void stop()

{

cout << "--- Passat:\tstop ---" << endl; // 模拟Passat停车

}

};

// 测试捷达

class TestJetta : public TestVehicle

{

public:

~TestJetta()

{

cout << "in the destructor of TestJetta..." << endl;

}

protected:

void start_up()

{

cout << "--- Jetta:\tstart up ---" << endl; // 模拟按Jetta的喇叭

}

void blow_horn()

{

cout << "--- Jetta:\tblow the horn ---" << endl; // 模拟按Jetta的喇叭

}

void run()

{

cout << "--- Jetta:\trun ---" << endl; // 模拟Jetta行驶

}

void turn()

{

cout << "--- Jetta:\ttrun ---" << endl; // 模拟Jetta转弯

}

void brake()

{

cout << "--- Jetta:\tbrake ---" << endl; // 模拟Jetta刹车

}

void stop()

{

cout << "--- Jetta:\tstop ---" << endl; // 模拟Jetta停车

}

};

// TemplateMethod.cpp

#include "TemplateMethod.h"

int main(int argc, char** argv)

{

// 测试帕沙特

TestVehicle *tvPassat = new TestPassat();

tvPassat->test();

cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;

// 测试捷达

TestVehicle *tvJetta = new TestJetta();

tvJetta->test();

cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;

delete tvPassat;

delete tvJetta;

return 0;

}

运行结果:

Start to test....

--- Passat: start up ---

--- Passat: blow the horn ---

--- Passat: run ---

--- Passat: trun ---

--- Passat: brake ---

--- Passat: stop ---

Test finished...

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Start to test....

--- Jetta: start up ---

--- Jetta: blow the horn ---

--- Jetta: run ---

--- Jetta: trun ---

--- Jetta: brake ---

--- Jetta: stop ---

Test finished...

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

in the destructor of TestPassat...

in the destructor of TestVehicle...

in the destructor of TestJetta...

in the destructor of TestVehicle...

上述程序的UML类图:

25. C++实现Behavioral - Template Method模式 - 玄机逸士 - 玄机逸士博客

Template Method模式应该是GoF给出的23个模式中相对简单的一个。

posted @ 2013-03-08 15:47 Jacc.Kim 阅读(216) | 评论 (0)编辑 收藏

转载自:http://patmusing.blog.163.com/blog/static/1358349602010150224904/

也称为Policy模式。

定义一系列算法,把他们一个个封装起来,并且使他们可以相互替换。该模式使得算法可以独立于使用它的客户而变化。

“Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.”- GoF

在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到某个对象中,将会使该对象变得异常复杂;而且有时候支持不使用的算法也是一个性能负担。Strategy设计模式就是在运行时根据需要透明地更改对象的算法,将算法和对象本身解耦。

我们在编程中,经常碰到这样的情况:用不同的办法去做同一件事情,比如,

1. 将文件保存为不同的格式;

2. 用不同的压缩算法压缩一个文本文件;

3. 用不同的压缩算法压缩视频文件

4. 将同样的数据,用不同的图形显示出来:折线图、柱状图或者饼图;

5. 将用某种语言写的一个句子,翻译成为几种其他的语言。

客户程序告诉驱动模块(不妨称为Context),它将使用哪个算法(即所谓的strategypolicy),并请求Context执行该算法。

Strategy模式UML类图:

24. C++实现Behavioral - Strategy模式 - 玄机逸士 - 玄机逸士博客
v

角色:

Strategy

- 给所有支持的算法声明一个通用接口,Context使用该接口调用由ConcreteStrategy定义的算法。

ConcreteStrategy

- 按照Strategy给出的接口实现具体的算法。

Context

- 包含一个Strategy的引用;

- 可以由ConcreteStrategy对象对其进行配置。

业务示例:

将阿拉伯数字“520”分别翻译成中文、英语和俄语。

下面是具体C++代码:

// Strategy.h

#include <iostream>

#include <string>

#include <memory>

using namespace std;

// Strategy抽象类,用做借口

class Strategy

{

public:

virtual string substitute(string str) = 0;

public:

virtual ~Strategy()

{

cout << "in the destructor of Strategy..." << endl;

}

};

// 中文Strategy

class ChineseStrategy : public Strategy

{

public:

string substitute(string str)

{

size_t index = str.find("520");

string tempstr = str.replace(index, 3, "我爱你");

return tempstr;

}

public:

~ChineseStrategy()

{

cout << "in the destructor of ChineseStrategy..." << endl;

}

};

// 英语Strategy

class EnglishStrategy : public Strategy

{

public:

string substitute(string str)

{

size_t index = str.find("520");

string tempstr = str.replace(index, 3, "I love you");

return tempstr;

}

public:

~EnglishStrategy()

{

cout << "in the destructor of EnglishStrategy..." << endl;

}

};

// 俄语Strategy

class RussianStrategy : public Strategy

{

public:

string substitute(string str)

{

size_t index = str.find("520");

string tempstr = str.replace(index, 3, "Я люблю тебя");

return tempstr;

}

public:

~RussianStrategy()

{

cout << "in the destructor of RussiaStrategy..." << endl;

}

};

// Context

class Translator

{

private:

auto_ptr<Strategy> strategy;

public:

~Translator()

{

cout << "in the destructor of Translator..." << endl;

}

public:

void set_strategy(auto_ptr<Strategy> strategy)

{

this->strategy = strategy;

}

string translate(string str)

{

if(0 == strategy.get()) return "";

return strategy->substitute(str);

}

};

// Strategy.cpp

#include "Strategy.h"

int main(int argc, char** argv)

{

string str("321520");

Translator* translator = new Translator;

// 未指定strategy

cout << "No strategy: " << translator->translate(str) << endl;

cout << "--------------------------" << endl;

// 翻译成中文

auto_ptr<Strategy> s1(new ChineseStrategy());

translator->set_strategy(s1);

cout << "Chinese strategy: " << translator->translate(str) << endl;

cout << "--------------------------" << endl;

// 翻译成英语

auto_ptr<Strategy> s2(new EnglishStrategy());

translator->set_strategy(s2);

cout << "English strategy: " << translator->translate(str) << endl;

cout << "--------------------------" << endl;

// 翻译成俄语

auto_ptr<Strategy> s3(new RussianStrategy());

translator->set_strategy(s3);

cout << "Russian strategy: " << translator->translate(str) << endl;

cout << "--------------------------" << endl;

delete translator;

return 0;

}

运行结果:

No strategy:

--------------------------

Chinese strategy: 321我爱你

--------------------------

in the destructor of ChineseStrategy...

in the destructor of Strategy...

English strategy: 321I love you

--------------------------

in the destructor of EnglishStrategy...

in the destructor of Strategy...

Russian strategy: 321Я люблю тебя

--------------------------

in the destructor of Translator...

in the destructor of RussiaStrategy...

in the destructor of Strategy...

结果符合预期。

1. 从上面程序可以很容易看出,可以在运行时改变translator对象的行为;

2. 算法如果改变了,客户端程序不需要做任何改动,比如在EnglishStrategy的实现中将“520翻译成“Five hundred and twenty”,客户端代码无需任何改变;

3. 当需要增加新的算法时,比如要将“520”翻译成日语的“わたし爱してるあなた”,只需要增加一个具体的Strategy类,比如JapaneseStrategy类,并重写Strategy中声明的纯虚函数即可。这完全符合OCP

上述代码的UML类图:

24. C++实现Behavioral - Strategy模式 - 玄机逸士 - 玄机逸士博客

Strategy模式和State粗看起来非常相似,但他们的意图完全不同。他们主要的区别在于:

1. Strategy一次只能选择一个strategy(即算法),而State模式中,不同的状态有可能同时被激活;

2. Strategy封装的是算法,State封装的是状态;

3. Strategy所封装的算法(每个算法对应一个类),所做的事情相差无几,而State所封装的状态(每个状态对应一个类),往往颇不相同;

4. State模式中的状态迁移的概念,在Strategy中根本不存在。

posted @ 2013-03-08 15:39 Jacc.Kim 阅读(199) | 评论 (0)编辑 收藏

     摘要: 转载自:http://patmusing.blog.163.com/blog/static/13583496020101502024824/ 也称为Objects for States模式。 允许一个对象在其内部状态改变时改变其行为,从而使对象看起来似乎修改了类。 “Allow an object to alter its behavior when its internal...  阅读全文
posted @ 2013-03-08 15:24 Jacc.Kim 阅读(275) | 评论 (0)编辑 收藏

     摘要: 转载自:http://patmusing.blog.163.com/blog/static/13583496020101501923571/ 也称为Dependents或Publish-Subscribe模式。 定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。 “Define a one-to-many depende...  阅读全文
posted @ 2013-03-08 15:12 Jacc.Kim 阅读(249) | 评论 (0)编辑 收藏

     摘要: 转载自:http://patmusing.blog.163.com/blog/static/13583496020101501825958/ Aka. Token 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存其状态。这样以后就可以将该对象恢复到原先保存的状态。 “Without violating encapsulation, capture and ext...  阅读全文
posted @ 2013-03-08 14:51 Jacc.Kim 阅读(199) | 评论 (0)编辑 收藏

     摘要: 转载自:http://patmusing.blog.163.com/blog/static/1358349602010150177996/“Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from r...  阅读全文
posted @ 2013-03-08 14:33 Jacc.Kim 阅读(183) | 评论 (0)编辑 收藏

     摘要: 转载自:http://patmusing.blog.163.com/blog/static/13583496020101501613155/ “Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.&...  阅读全文
posted @ 2013-03-08 12:57 Jacc.Kim 阅读(218) | 评论 (0)编辑 收藏

仅列出标题
共14页: 1 2 3 4 5 6 7 8 9 Last