Programming 版 (精华区)

发信人: zhangyan (要跑1000M了), 信区: Programming
标  题: Conversations: Abstract Factory, Template Style
发信站: 哈工大紫丁香 (2001年06月16日13:56:30 星期六), 站内信件

Conversations: Abstract Factory, Template Style
Jim Hyslop and Herb Sutter
//翻译:HolyFire
//出处www.cuj.com
                设计模式之经验交流 :
------------- Abstract Factory, Template Style
            (Jim Hyslop and Herb Sutter)
Copyright 2001, Jim Hyslop and Herb Sutter
写于2001年, Jim Hyslop and Herb Sutter
------------------------------------------------------------------------
------------------------------------------------------------------------
--------------
"Do we know what it is?" I gestured at the device lying on the cold 
metal table before us. It had been one of the first to have been 
retrieved by the recon parties exploring the immense building buried 
below us in the ice.
我向倚着金属靠椅坐在我们面前的设计师比划着说:"我们该如何理解这个呢?"他
用极快的眼神将我审视了一遍然后将视线投向远方,当时我觉得好像陷入了冰窖一
般。
Jeannine shook her head. "Nyet, tovarisch. It could be a toaster, a 
hyperdrive motor, a child's toy, or just junk. Last week we thought we 
had the power system worked out, for this and the other devices, but 
when we ran the juice through them nothing happened. The techs are 
back to the drawing board as far as the power goes, but they're 
hopeful that they'll get it right soon."
Jeannine摇了摇头。"不明白吗?同志。他可以是一个胜利者,一个火箭推进器,
一个宝宝的玩具,也可以是一个舢板。我想我们下个星期就要完成动力系统,就是
这个以及其他的设计,但是我们运行这个废物时这些玩艺从头到尾什么也没干。设
计院的设计图上这些设计一直到动力运作,但是设计师们却希望他们能尽快得到正
确的结果"
"And what makes them think they will?"
"是什么让他们有这样的想法?"
"Hope."
"只是个期望而已"
I glanced at the clock on the wall of the chamber. "Well, it's nearly 
time. I'm beat, and I'm freezing. Every time we ask the recon teams to 
give us something new to work on, they produce something new and 
different. I just wish we could understand even one of these."
我瞥了一眼墙上的钟。"现在到好,这么紧迫的时间,我想我不行了,我无法进行
下去了。每次我们向视察小组要求新的工作的时候,他们总是提供一些新的不同的
工作,我只是希望他们能理解工作上需要一些连贯性"
"I wish we knew more about what was coming out of our little 
historical Abstract factory' here," Jeannine agreed.
Jeannine似乎赞同我的观点"我想在这里我们更能理解一点展现在我们面前的过去
使用的Abstract factory
"That reminds me of something that happened to me back when-"
"这使我想起了曾经经历过的那件事----"
Jeannine rolled her eyes. "Tell me when we get someplace warm."
Jeannine闪动着智慧的双眼"告诉我那个让我们激动的时刻"
------------------------------------------------------------------------
------------------------------------------------------------------------
--------------
"Bad news," I called glumly over the cubicle wall to Wendy.
"坏消息!"我招呼着卧室隔壁闷闷不乐的Wendy.。
"Wazzup?" she gophered up.
"怎么了"她窜了起来
"You know that class I worked on last week?"
"你知道我上个星期使用的class吗"
"Not intimately, but do go on."
"不是很清楚,不过他正在运作"
I ignored that. "Well," I continued, "I have to create a class factory 
for it. The Guru suggested I look at the class factory the client 
group wrote."
"很好"我打断了她继续说道"我为它作了一个class factory。Guru启示我将这个
class factory做成客户群的需要。
"Yeah, so?" Then a sudden look of dismay crossed her face: "Oh. Bob 
wrote that, didn't he?"
"是这样啊"她的脸上闪过一片阴罹:"但是Bob完成了它,不是吗?"
I nodded glumly. "Well, one thing I'll give him credit for - every 
time I crack open his code, I learn how not to do something." Wendy 
giggled and sank back into her chair.
我郁闷的点点头"唯一值得庆幸的事是,我取得了他的信任----任何时候我都可以
改进他的代码,我知道什么时候有些事不该作" Wendy哈哈一笑又倒在她的椅子里
了。
I sighed and checked out the source code. It wasn't quite as bad as I 
had anticipated. There was only one humongous series of cascading if 
statements - I had expected a lot worse. Still, it was pretty hairy 
code, so with the Guru's blessing I set about implementing an Abstract 
Class Factory [1]. Absent any requirements for multithreading or other 
concurrency, I decided to implement the factory as a singleton:
我叹了口气埋头察看那些个源代码去了。这些代码不象我预计的那样糟糕,他们只
是一个巨大的if语句的一层层的嵌套-----我更想的是看到更多的毛病,但是他还
是那个只是一堆杂乱的代码。Guru保佑,我看到了实现Abstract Class Factory的
影子。在缺少需求和杂乱无章的情况下,我决定将factory实现成一个singleton:

class BaseFactory
{
    typedef std::auto_ptr<Base> (*BaseCreateFn)();
    typedef std::map<std::string, BaseCreateFn> FnRegistry;
    FnRegistry registry;

    BaseFactory() {}
    BaseFactory(const BaseFactory &); // Not implemented
    BaseFactory & operator=(const BaseFactory &); // Not implemented

public:
    static BaseFactory & instance() { static BaseFactory bf; return bf;
 }

    bool RegCreateFn(const std::string &, BaseCreateFn);

    std::auto_ptr<Base> Create(const std::string &) const;
};

bool BaseFactory::RegCreateFn(const std::string & className, 
BaseCreateFn fn)
{
    registry[className] = fn;
    return true;
}

std::auto_ptr<Base> BaseFactory::Create(const std::string &className) 
const
{
    std::auto_ptr<Base> theObject(0);
    FnRegistry::const_iterator regEntry = registry.find(className);
    if (regEntry != registry.end()) 
    {
        theObject = regEntry->second();
    }
    return theObject;
}
In the Base implementation file, I added:
在基类实现文件里,我加上了:
namespace 
{
    std::auto_ptr<Base> CreateBase()
    {
        return std::auto_ptr<Base>(new Base);
    }

    bool dummy = BaseFactory::instance().RegCreateFn("Base", 
CreateBase);
}
"OK, that's cool," I thought. "You register a function with the factory,
 and creating an instance is as simple as one, two, three:"
"太酷了!"我想道"你使用factory来注册一个函数,他将创建一个实例,one, 
two, three,就这么简单"
int main()
{
    std::auto_ptr<Base> anObject = BaseFactory::instance().
Create("Base");
}

I then proceeded to create a derived class, to test creating it via 
the factory. In the derived class's implementation file, I added:
我接着派生了一个类,用来测试用这个factory创建。
在派生类实现文件里,我加上了:
namespace 
{
    std::auto_ptr<Derived> CreateDerived()
    {
        return std::auto_ptr<Derived>(new Derived);
    }

    bool dummy = BaseFactory::instance().RegCreateFn("Derived", 
CreateDerived);
}

But the compiler stopped me cold - it complained that it couldn't 
convert CreateDerived to the correct type. After puzzling over it for 
a moment, I remembered the problem I had experienced previously with 
implicit conversions to pointers-to-Base [2]. I realized I had just 
run into another situation where the compiler couldn't implicitly 
convert the pointers, so I had to rewrite the create function slightly:

但是编译器罢工了----他一直抱怨CreateDerived不能转化正确的类型。迷惑了一
阵后,我想起了这个问题,我先前的经验告诉我将指针转化为BASE是正确的选择。
我认识到我刚刚陷入了另一个问题,编译器不能隐含的转化指针。,所以我重写了
创建函数部分
namespace 
{
    std::auto_ptr<Base> CreateDerived()
    {
        return std::auto_ptr<Base>(new Derived);
    }

    bool dummy = BaseFactory::instance().RegCreateFn("Derived", 
CreateDerived);
}
Looking back at the base class, I realized that the registration code 
was almost identical, so I created a macro to wrap it up:
回头看看基类部分,我发现注册部分的代码几乎完全一样,所以我用一个宏包含了
这一切
#define REGISTER_CLASS(BASE_CLASS, DERIVED_CLASS) \
namespace \
{ \
    std::auto_ptr<BASE_CLASS> Create##DERIVED_CLASS() \
    { \
        return std::auto_ptr<BASE_CLASS>(new DERIVED_CLASS); \
    } \
    bool dummy=BaseFactory::instance().RegCreateFn( \
        #DERIVED_CLASS, Create##DERIVED_CLASS); \
}
Using the macro was quite simple:
使用这个宏就简单多了
REGISTER_CLASS(Base, Base)

"Not bad for a few hours' work," I muttered when I was done.
"这几个小时收获不错"完成后我喃喃说道。
"Yes, indeed, my child. But you can do better."
"真的吗,我的小菜鸟,不过我能作的更好。"
I jumped yet again at the Guru's soft voice behind me. "Wha-?"
"哇-"Guru柔和的声音却差点让我跳起来。
"Macro expansions like that," she explained, "are difficult to read 
and understand, and macros are not type safe. Also, what is the 
purpose of the bool dummy variable?"
"像这样展开宏"她不紧不慢的解释道"是很难以阅读和理解的,而且宏不是类型安
全的。而且,这个bool型的变量dummy有什么用意呢?"
"Well," I said, slightly defensively, "it was the only way I could think
 of to ensure that the registration function got called automatically. I
 wanted to get away from the typical factory code that requires a 
modification each time you add a new class."
"是这样的"我些微的为自己辩护,"只有这样我才能确保注册函数被自动调用了。
我想抛弃传统factory编码那需要在每加入一个新类的时候都要进行修改。
She inclined her head. "Wise thinking, my child. However, your factory 
is not very generic. We are dealing with more and more classes that 
require abstract factories. I want you to create a factory that will 
handle, not require, modification for each class hierarchy it will be 
used on."
她转过脸来"英明的想法,我的小菜鸟。但是,你的factory还不是很通用。我们对
待越来越多的类的时候需要用的是abstract factories。我想要你建立一个
factory,他将这样处理,没有要求,可以被它的子类修改,那它将更常用"
"A generic abstract factory? That's a pretty tall order, isn't it?"
"一个通用的abstract factory?多么离奇的要求,不是吗?"
"My young apprentice, you are not afraid of a challenge, are you? 
Experience is by industry achieved...' "" ?.. and perfected by the swift
 course of time,'
"我的小学生,你根本不惧挑战,对吗?经验是从工作中得来的…,熟能生巧啊"
I finished [3]. "No, I'm not afraid of the challenge, but I don't want 
the swift course of time to turn the schedule aside."
我结束了她发言"不,我不能为了熟能生巧把进度放在一边啊"
"You are most of the way there already. All you need to do is think 
generically," she observed.
"你总是走那些老套路。你最需要的不是考虑通用吗"她坚持着。
"Think generically... as in, templates!" I exclaimed and turned back 
to my monitor. A few minutes later, I glanced behind me and saw that the
 Guru had disappeared again as silently as she had appeared. I shivered,
 but only slightly, and went back to work.
"考虑通用性,那不就是,模板!"我突然一呼而出立刻转向显示器,几分钟后,我
深怕Guru悄悄的消失正如她悄悄的出现,我不禁有些颤抖,但是很快就进入了工作
状态。
After a short while, I came up with a factory template:
短短一瞬间,我完成了factory template:
template <class ManufacturedType, typename ClassIDKey=std::string>
class GenericFactory
{
    typedef std::auto_ptr<ManufacturedType> (*BaseCreateFn)();
    typedef std::map<ClassIDKey, BaseCreateFn> FnRegistry;
    FnRegistry registry;

    GenericFactory();
    GenericFactory(const GenericFactory&); // Not implemented
    GenericFactory &operator=(const GenericFactory&); // Not 
implemented

public:
    static GenericFactory &instance();

    void RegCreateFn(const ClassIDKey &, BaseCreateFn);

    std::auto_ptr<ManufacturedType> Create(const ClassIDKey 
&className) const;
};
I realized that not all classes would necessarily need a std::string 
as the key, so I made the key type a parameter to the template. The 
implementation of each function was the same as I had used for 
BaseFactory, except for the registration function. I came up with a more
 elegant template for that:
我认识到不是所有的类用到了std::string这个key,所以我将这个key做成了参数
的形式。每个函数的实现我都用到了BaseFactory,除了注册函数。我使用了更多
的好用的tempalte:
template <class AncestorType, class ManufacturedType, typename 
ClassIDKey=std::string>
class RegisterInFactory
{
public:
    static std::auto_ptr<AncestorType> CreateInstance()
    {
        return std::auto_ptr<AncestorType>(new ManufacturedType);
    }

    RegisterInFactory(const ClassIDKey &id)
    {
        GenericFactory<AncestorType>::instance().RegCreateFn(id, 
CreateInstance);
    }
};
Now, each class derived from the base class simply had to add one line 
to get a type-safe registration of the creation function:
现在,每个从这个类派生的类都简单的加上了一个类型安全的内联的注册函数用来
创建:
RegisterInFactory<Base, Base> registerMe("Base");
The RegisterInFactory template's constructor registers the name of the 
class in the creation registry [4].
这个RegisterInFactorytempalte的构造函数注册了类名
I glanced behind me, just in time to see the Guru approaching. I 
smiled to myself; 
for once I was slightly ahead of her game.
我向后偷偷瞄了一眼,正好看到Guru走过来,在她这个竞赛里略占上风,我不禁得
意洋洋。
 "Very good, my apprentice," she said, coming up behind me. "Your 
factory is generic, portable, and does not rely on registration tables,
 DLL sentries, or other cumbersome techniques."
"非常好,我的学生,"她走到我后面时发话了"你的factory通用了,很便捷,不依
赖注册表,DLL以及其他繁琐的技术。"
"There is one drawback, though," I interrupted. "Because the 
registration relies on a static object being initialized, there is no 
guarantee that all the creation functions will be registered if you 
use the factory before main begins execution."
"尽管如此这里还有一点缺陷"我打断了她的话"因为注册依赖一个静态对象的初始
化,使用这个factory他还不能保证所有的创建函数都能在main执行前被注册"
"Exactly, my apprentice, your factory is subject to the Static 
Initialization Order Fiasco, as explained by the prophet Cline [5]." She
 turned to leave.
"非常正确,我的学生,你的factory受到了静态对象初始化次序的影响是一大败笔
,就像先知Cline解释的一样"她开始准备离开。
"Wait a second," I called. The Guru turned back. I was trying to 
figure out a graceful way of asking the question that was on my mind. 
The Guru patiently tucked a lock of her hair behind her ear while she 
waited. "About Bob. If he's such a bad programmer," I managed to say, 
"how come..."
"请等一会儿"我挽留道。Guru转了回来。我开始努力砌词来完美的表达我想询问的
意图。Guru很有耐心在一边整理头发。"比方说Bob。如果他写了一堆糟糕的程式,
"我开始笨拙的拼凑胡言乱语"他开始…"
"Why is he still here?" the Guru supplied. I nodded. The Guru looked 
down in thought. 
"那为何他还留在这里?"Guru补充道。我点点头。Guru陷入了沉思。
"Have you noticed that Bob hangs out with the execs? Senior management 
thinks he's some sort of golden boy and can do no wrong. Because of 
our... um... past, Bob has them convinced that any of my complaints 
about his job performance are just the petty grievances of a bitter 
ex-wife. And, according to him, anyone who agrees with me has been drawn
 into my little plots against him - his words, not mine."
"你有没有注意到Bob测试的成绩很突出?高层的管理员认为他是一个难得的人才因
为他很少出错。因为我们…恩啊…算了,Bob深的他们信任,所以我即使有所抱怨
也是无济于事。还有,看看他,人人都买我的帐除了他,他总和我不一致"
"Man, that must be tough. Why do you put up with it? You could find a 
new job like that." I snapped my fingers.
"天哪,这一定不好受。你怎能容忍这些?你可以找到别的工作"我握着她的手。
She shrugged. "Other than Bob, I like it here. Besides, if I left, I 
wouldn't get the satisfaction of bugging the heck out of him with this 
act." 
她耸耸肩。"除了Bob,我还是很喜欢这里。此外,如果我离开了,还真找不到他这
样能让我满意的找到bug并解决的人呢"
We both laughed. "Seriously, though," she continued, "this company has a
 lot of opportunities for career growth. For example, our new biomedical
 device division is going to need a head of software development - 
I've applied for the position."
"Cool! Good luck," I said. The Guru nodded her thanks. I turned back 
to my workstation, to put the finishing touches on the abstract 
factory template.
我们相视而笑。"说真的,尽管如此"她继续说道"这个公司有很多机会发展的。比
方说,我们的新临床分割系统在软件业处于领先水平----我已在这方面有应用了。
"酷!祝你好运"我祝福道。Guru颔首以示谢意。我回到工作室,完成abstract 
factory template这一杰作的收尾工作。
------------------------------------------------------------------------
------------------------------------------------------------------------
--------------
It was late at night a few days later when the news came, but I didn't 
find out about it until I got up the next morning. Still bleary-eyed, 
I was walking into the mess when the unusual level of noise made me 
put my hands over my ears and wince. "What's with all the chatter?" I 
muttered grumpily at the dozen people who were already there, talking 
excitedly.消息到来的这几天我都干到很晚,不干完这些明天我又不知道什么时候
就要爬起来。正当我睡眼朦胧的时候,我走进混乱不堪的工作室时一些不寻常的杂
乱声引起了我的注意,我将手放在额头上窥视者。"是什么这么吵?"我不满的嘀咕
着,这时有十二个人正在那儿,兴奋的交谈着。
"It's too early for you guys to be this perky."
"你这个家伙这么早就完成了,相当有自信啊"
It was Major Gilb who answered, smiling. "We think we've got it, my boy,
 we think we do."
这是一个叫Major Gilb对我说的话,他正在向我微笑"我想我们成功了,我的小伙
子,我们做到了!"
"What?" I grumped through mental cobwebs.
"什么?"我丈二摸不着头脑。
"Looks like the power's on," Jeannine said simply.
"你看,动力已经开动了" Jeannine轻描淡写的说道。

--
※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 天外飞仙]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:214.535毫秒