游戏开发论坛

 找回密码
 立即注册
搜索
查看: 15644|回复: 16

简单实现设计模式

[复制链接]

15

主题

83

帖子

123

积分

注册会员

Rank: 2

积分
123
发表于 2004-4-14 13:31:00 | 显示全部楼层 |阅读模式
发完这个贴,要休息一段时间才动笔了。


下面这些设计模式的实现都是一些简单的示例实现,如果你希望更稳固,更方便的实现,请自己修改。我以Gof的书作为蓝本,实现里面可以被抽象的设计模式,里面使用Loki, Boost, STL的一些东西,如果有疑问的话请翻阅相关书籍。

//***************************************************************************

Abstract Facrory 抽象工厂:

目的:
为了把产品的创建抽象化
为了隐藏产品的实现
为了实现一序列产品的安全创建

实现:

namespace Noir_Impl
{
        template<class P>
        struct CAF_Product { P* Create_Impl() { return new P; } };

        template<class CProductList>
        class CAF_AbstractFactory : public Loki::GenScatterHierarchy< CProductList, CAF_Product > { };
};

//IProductList是你的抽象工厂接口,CProductList是你的抽象工厂的实现

template<class IProductList, class CProductList>
struct Simple_AbstractFactory : public IProductList, private Noir_Impl::CAF_AbstractFactory< CProductList >
{
        template<class IP> IP* Create()
        {
                typedef TypeAt< CProductList, IndexOf< IProductList, IP >::value > CP;
                return CP::Create_Impl();
        }
};

//***************************************************************************

Builder 产生器:

目的:
为了实现通过继承修改产品创建的某个环节

实现:

template<int stepnum> struct IBuilder;  //产生器接口,stepnum表示分几步构造

template<>
struct IBuilder<0>
{
        virtual void BuildPart(Loki::Int2Type<0>&) = 0;
};

template<int stepnum>
struct IBuilder : public IBuilder< stepnum - 1 >
{
        virtual void BuildPart(Loki::Int2Type<stepnum>&) = 0;
};

template<int stepnum, class T>
struct Simple_Builder //产生器
{
        template<int stepnum> static void Build(T* obj)
        {
                obj->IBuilder<stepnum>::BuildPart(Loki::Int2Type<stepnum>());
                Build< stepnum - 1 >(obj);
        }
        template<> static void Build<0>(T* obj)
        {
                obj->IBuilder<0>::BuildPart(Loki::Int2Type<0>());
        }
};

//***************************************************************************

Clone Factory 克隆工厂:

目的:
为了不关心我们将创建的对象的类别
为了避免类爆炸,通过运行时的参数指定来创建新的“类”

实现:

namespace Noir_Impl
{
        template<class P>
        class CCL_Product
        {
        private:
                P* m_obj;
        public:
                CCL_Product() : m_obj(NULL) { }
                void Set_Impl(P* p) { assert(p); m_obj = p; }
                P*   Clone_Impl()   { assert(m_obj); return new P(m_obj); }
        };

        template<class CProductList>
        class CCL_CloneFactory : public Loki::GenScatterHierarchy< CProductList, CCL_Product > { };
};

template<class IProductList, class CProductList>  //IProductList是你的克隆工厂接口,CProductList是你的克隆工厂的实现
struct Simple_CloneFactory : public IProductList, private Noir_Impl::CCL_CloneFactory< CProductList >
{
        template<class IP> void Set(IP* p)
        {
                typedef TypeAt< CProductList, IndexOf< IProductList, IP >::value > CP;
                CP::Set_Impl(p);
        }
        template<class IP> IP* Clone()
        {
                typedef TypeAt< CProductList, IndexOf< IProductList, IP >::value > CP;
                return CP::Clone_Impl();
        }
};

//***************************************************************************

FactoryMethod 对象工厂:

目的:
为了在运行时通过外部信息来创建产品
当不关心对象的类别的时候

实现;

#define CLASSID(x)   static const int CLASS_ID = x;

template< class IC, class PList >
struct Simpe_FactoryMethod : public Loki::SmallObject<>
{
        template<int index> IC* Create(int id)
        {
                assert( id >= 0 );
                typedef TypeAt&ltList, index>::Result CClass;
                if( id == CClass::CLASS_ID )
                        return new CClass;
                else
                        return Create<index - 1>(id);
        }
        template<> IC* Create<0>(int id)
        {
                assert( id >= 0 );
                typedef TypeAt<PList, index>::Result CClass;
                if( id == CClass::CLASS_ID )
                        return new CClass;
                else
                        assert(0);
        }
};

//***************************************************************************

Singleton 单件:

目的:
一个安全的全局变量,你可以完全监控他的行为

实现:

template<class T>
class Simple_Init
{
private:
        static T _obj;
public:
        static T& Instance() { return _obj; }
};
template<class T>
T Simple_Init<T>::_obj;


template<class T>
class Lazy_Init
{
public:
        static T& Instance() { static T _obj; return _obj; }
};

template< class T, template<class> class S=Simple_Init>
class Simple_Singleton : private S<T>, private boost::noncopyable, private noncreatable, public T
{
private:
        operator &() const;
        operator T() const;
public:
        using S<T>::Instance;

        bool Init()   { return Instance().Init();   }
        bool UnInit() { return Instance().UnInit(); }
};



//***************************************************************************

Adapter 适配器:

目的:
为了把不吻合或不搭配的接口转换成我们希望的接口

实现:
无固定实现

//***************************************************************************

Bridge 桥接:

目的:
抽象出实现的“核心部分”和“扩展部分”,“扩展部分”由“核心部分”实现,通过切换“核心部分”来使“扩展部分”相应的改变,从而达到切换整个系统的目的

实现:
无固定实现,其实就是Policy的设计方法的一个运用

//***************************************************************************

Composite 组合:

目的:
为了把对象以及他们的组合体“一视同仁”

实现:

template<class T>
class Simple_Composite_Train : private Safe_Dector, public T, public Loki::SmallObject<>
{
private:
        typedef Simple_Composite_Train<T> ClassType;
        std::list<ClassType*> m_childlist;
public:
        void ChildAs(ClassType* p)
        {
                assert(p);
                p->m_childlist.pus_back(this);
        }
        void ParentAs(ClassType* p)
        {
                assert(p);
                p->ChildAs(this);
        }
        void CutFromParent(ClassType* p)
        {
                assert(p);
                std::remove(p->m_childlist.begin(), p->m_childlist.end(), p);
        }
        void RemoveChild(ClassType* p)
        {
                assert(p);
                p->CutFromParent(this);
        }
        void RemoveAllChild()
        {
                DoFunc0<RemoveChild>();
        }

        template<typename void(ClassType::* func)()>
        void DoFunc()
        {
                func();
                std::for_each(m_childlist.begin(), m_childlist.end(), boost::bind(func, _1));
        }
        template<class Param1, typename void(ClassType::* func)(Param1*)>
        void DoFunc(Param1* p1)
        {
                func(p1);
                std::for_each(m_childlist.begin(), m_childlist.end(), boost::bind(func, _1, p1));
        }
        template<class Param1, class Param2, typename void(ClassType::* func)(Param1*, Param2*)>
        void DoFunc(Param1* p1, Param2* p2)
        {
                func(p1, p2);
                std::for_each(m_childlist.begin(), m_childlist.end(), boost::bind(func, _1, p1, p2));
        }
        template<class Param1, class Param2, class Param3, typename void(ClassType::* func)(Param1*, Param2*, Param3*)>
        void DoFunc(Param1* p1, Param2* p2, Param3* p3)
        {
                func(p1, p2, p3);
                std::for_each(m_childlist.begin(), m_childlist.end(), boost::bind(func, _1, p1, p2, p3));
        }
        /*......*/
};

template<class T>
class Simple_Composite_Resever : private Safe_Dector, public T, public Loki::SmallObject<>
{
private:
        typedef Simple_Composite_Resever<T> ClassType;
        ClassType* m_parent;
public:
        Simple_Composite_Resever() : m_parent(NULL) { }

        void ChildAs(ClassType* p)
        {
                assert(p);
                m_parent = p;
        }
        void ParentAs(ClassType* p)
        {
                assert(p);
                p->ChildAs(this);
        }
        void CutFromParent()
        {
                assert(p);
                m_parent = NULL;
        }

        template<typename void(ClassType::* func)()>
        void DoFunc()
        {
                ClassType* ptemp = this;
                while(!ptemp)
                {
                        temp->func();
                        temp = temp->m_parent;
                }
        }
        template<class Param1, typename void(ClassType::* func)(Param1*)>
        void DoFunc(Param1* p1)
        {
                ClassType* ptemp = this;
                while(!ptemp)
                {
                        temp->func(p1);
                        temp = temp->m_parent;
                }
        }
        template<class Param1, class Param2, typename void(ClassType::* func)(Param1*, Param2*)>
        void DoFunc(Param1* p1, Param2* p2)
        {
                ClassType* ptemp = this;
                while(!ptemp)
                {
                        temp->func(p1, p2);
                        temp = temp->m_parent;
                }
        }
        template<class Param1, class Param2, class Param3, typename void(ClassType::* func)(Param1*, Param2*, Param3*)>
        void DoFunc(Param1* p1, Param2* p2, Param3* p3)
        {
                ClassType* ptemp = this;
                while(!ptemp)
                {
                        temp->func(p1, p2, p3);
                        temp = temp->m_parent;
                }
        }
        /*......*/
};

//***************************************************************************

Decorator 修饰:

目的:
为了动态的增加对象的职能:

实现:

template<class T>
class Simple_Decorator : public Simple_Composite_Resever<T> { };

//***************************************************************************

Facade 外观:

目的:
为复杂的借口提供一个简单的访问点

实现:

namespace Noir_Impl
{
        template <class AtomicType, class Base>
        struct Empty_Unit { };
};

template<class TList>
class Simple_Facade : public Loki::GenLinearHierarchy<TList, Noir_Impl::Empty_Unit>  { };

//***************************************************************************

FlyWieght 享元

目的:
为了使数量巨大的对象共享大量重复的对象或属性

实现:

namespace Noir_Impl
{
        const int MAX_FLYWEIGHT_NUM = 256;

        template<class T>
        class FlyWeight_Unit
        {
        private:
                T* m_fwlist[MAX_FLYWEIGHT_NUM];
        public:
                FlyWeight_Unit() { ZeroMemory(m_fwlist, sizeof(m_fwlist)); }

                int Insert(T* p)
                {
                        assert(p);
                        for(int iter=0; iter<MAX_FLYWEIGHT_NUM; iter++)
                        {
                                if(m_fwlist[iter] == NULL)
                                {
                                        m_fwlist[iter] = p;
                                        return iter;
                                }
                        }
                }

                int Remove(T* p)
                {
                        assert(p);
                        for(int iter=0; iter<MAX_FLYWEIGHT_NUM; iter++)
                        {
                                if(m_fwlist[iter] == p)
                                {
                                        S_DELETE(m_fwlist[iter]);
                                        return iter;
                                }
                        }
                        assert(0);
                        return MAX_FLYWEIGHT_NUM;
                }

                void Clear()
                {
                        for(int iter=0; iter<MAX_FLYWEIGHT_NUM; iter++)
                        {
                                S_DELETE(m_fwlist[iter]);
                        }
                }

                T* Get(int iter)
                {
                        assert( iter >= 0 && iter < MAX_FLYWEIGHT_NUM );
                        assert( m_fwlist[iter] );
                        return m_fwlist[iter];
                }
        };
};

template<class fwclasslist>
struct Simple_FlyWeight : public Loki::GenScatterHierarchy<fwclasslist, Noir_Impl::FlyWeight_Unit>
{
        template<class T> int Insert(T* p)  { return FlyWeight_Unit<T>::Insert(p); }
        template<class T> int Remove(T* p)  { return FlyWeight_Unit<T>::Remove(p); }
        template<class T> void Clear()      { FlyWeight_Unit<T>::Clear(); }
        template<class T> T* Get(int iter)  { return FlyWeight_Unit<T>::Get(iter); }
};

//***************************************************************************

Porxy 代理:

目的:
为了对某个对象增加某些辅助能力或限制而且对使用者完全不透明

实现:
没有固定实现



Chain Of Responsibility 职责链:

目的:
为了把消息发送者和消息处理者解偶

实现:

template<class T>
class Simple_ChainOfResp_Train : public Simple_Composite_Train<T>
{
public:
        template<typename void(ClassType::* func)()>
        bool DoResp()
        {
                if( func() )  return true;

                list<ClassType*>::iterator i(m_childlist.begin());
                list<ClassType*>::iterator e(m_childlist.end());
                for(; i!=e; ++i)  if( ((*i)->*func)() ) return true;

                return false;
        }
        template<class Param1, typename void(ClassType::* func)(Param1*)>
        bool DoResp(Param1* p1)
        {
                if( func(p1) )  return true;

                list<ClassType*>::iterator i(m_childlist.begin());
                list<ClassType*>::iterator e(m_childlist.end());
                for(; i!=e; ++i)  if( ((*i)->*func)(p1) ) return true;

                return false;
        }
        template<class Param1, class Param2, typename void(ClassType::* func)(Param1*, Param2*)>
        bool DoResp(Param1* p1, Param2* p2)
        {
                if( func(p1, p2) )  return true;

                list<ClassType*>::iterator i(m_childlist.begin());
                list<ClassType*>::iterator e(m_childlist.end());
                for(; i!=e; ++i)  if( ((*i)->*func)(p1, p2) ) return true;

                return false;
        }
        template<class Param1, class Param2, class Param3, typename void(ClassType::* func)(Param1*, Param2*, Param3*)>
        bool DoResp(Param1* p1, Param2* p2, Param3* p3)
        {
                if( func(p1, p2, p3) )  return true;

                list<ClassType*>::iterator i(m_childlist.begin());
                list<ClassType*>::iterator e(m_childlist.end());
                for(; i!=e; ++i)  if( ((*i)->*func)(p1, p2, p3) )  return true;

                return false;
        }
        /*......*/
};

template<class T>
class Simple_ChainOfResp_Resever : public Simple_Composite_Resever<T>
{
public:
        template<typename void(ClassType::* func)()>
        bool DoResp()
        {
                ClassType* ptemp = this;
                while(!ptemp)
                {
                        if( temp->func() ) return true;
                        temp = temp->m_parent;
                }

                return false;
        }
        template<class Param1, typename void(ClassType::* func)(Param1*)>
        bool DoResp(Param1* p1)
        {
                ClassType* ptemp = this;
                while(!ptemp)
                {
                        if( temp->func(p1) ) return true;
                        temp = temp->m_parent;
                }

                return false;
        }
        template<class Param1, class Param2, typename void(ClassType::* func)(Param1*, Param2*)>
        bool DoResp(Param1* p1, Param2* p2)
        {
                ClassType* ptemp = this;
                while(!ptemp)
                {
                        if( temp->func(p1, p2) ) return true;
                        temp = temp->m_parent;
                }

                return false;
        }
        template<class Param1, class Param2, class Param3, typename void(ClassType::* func)(Param1*, Param2*, Param3*)>
        bool DoResp(Param1* p1, Param2* p2, Param3* p3)
        {
                ClassType* ptemp = this;
                while(!ptemp)
                {
                        if( temp->func(p1, p2, p3) ) return true;
                        temp = temp->m_parent;
                }

                return false;
        }
        /*......*/
};

//***************************************************************************

Command 命令:

目的:
把命令发起者和执行者解偶

实现:
boost::signals

//***************************************************************************

Interpreter 解释器:

目的:
为了完全动态的控制和修改程序

实现:
boost::regex

//***************************************************************************

iterator 迭代器:

目的:
把容器的内部表示和访问解偶

实现:
没有固定的实现,STL有一些范例

//***************************************************************************

Mediator 中介者:

目的:
把对象间的交互抽象出来,这样可减少交互对象之间的偶合,因为偶合被转移到中介者身上

实现:
无固定实现

//***************************************************************************

Memento 备忘录:

目的:
为了实现场景的恢复

实现:

注意下面这个实现在不同的编译器和平台上都有不同的表现,但对于VC7来说是对的

namespace Noir_Impl
{
        template<class T>
        struct Raw_Copy_Impl : public Relex<T>
        {
                void Copy_Impl(T* dest, T* src)
                {
                        if(dest == src) return;
                        mempcy(dest, src, sizeof(T));
                }
        };
};
template<class T, template<class> class Copy=Noir_Impl::Raw_Copy_Impl>
class Simple_Memento : public T, private Copy<Simple_Memento> //一定要注意字节对齐问题
{
public:
        T* GetMemento() { return new MementoType(this); }
        void SetMemento(T* p) { assert(p); Copy_Impl(this, p); }
};

//***************************************************************************

Observer 观察者:

目的:
为了实现一种一对多的关系,当一个对象发生变化,那么所有依赖他的对象都需要发生变化

实现:

template<class I>
class Simple_Observer_Target_Impl
{
private:
        std::vector<I*> m_observerlist;
public:
        void insert(I* p) { assert(p); m_observerlist.insert(); }
        void remove(I* p)
        {
                assert(p);
                m_observerlist.erase( std::remove( m_observerlist.begin(), m_observerlist.end(), p ) );
        }
        void clear() { m_observerlist.clear(); }

        void fire_all(void(*func)())
        { std::for_each( m_observerlist.begin(), m_observerlist.end(), boost::bind( func, _1 ) ); }

        template<class T1>
        void fire_all(void(*func)(T1), T1 t1)
        { std::for_each( m_observerlist.begin(), m_observerlist.end(), boost::bind( func, _1, t1 ) ); }

        template<class T1, class T2>
        void fire_all(void(*func)(T1, T2), T1 t1, T2 t2)
        { std::for_each( m_observerlist.begin(), m_observerlist.end(), boost::bind( func, _1, t1, t2 ) ); }

        template<class T1, class T2, class T3>
        void fire_all(void(*func)(T1, T2, T3), T1 t1, T2 t2, T3 t3)
        { std::for_each( m_observerlist.begin(), m_observerlist.end(), boost::bind( func, _1, t1, t2, t3 ) ); }

        template<class T1, class T2, class T3, class T4>
        void fire_all(void(*func)(T1, T2, T3, T4), T1 t1, T2 t2, T3 t3, T4 t4)
        { std::for_each( m_observerlist.begin(), m_observerlist.end(), boost::bind( func, _1, t1, t2, t3, t4 ) ); }
};

template<class I>
class Simple_Observer_Target : public Simple_Singleton< Simple_Observer_Target_Impl<I> > { };

//***************************************************************************

State 状态:

目的:
为了方便的在改变了状态的情况下改变行为

实现:
无固定实现

//***************************************************************************

Strategy 策略:

目的:
又叫Policy,一言难尽,请看我的其他帖子

实现:
无固定实现

//***************************************************************************

Template Method 模板方法:

目的:
抽象出算法和流程框架,然后允许子类改变实现的细节

实现:
使用Policy的思想

//***************************************************************************

Visitor 访问者:

目的:
为了增加一个类体系的能力

实现:

#define MAKE_VISIT()  \
public: \
        template<class U>  \
        void Accept(U& obj) \
        {  \
                obj.Visit( *this );  \
        }

namespace Noir_Impl
{
        template <class AtomicType, class Base>
        struct Visit_Unit
        {
                virtual void Visit(AtomicType& obj) { }
        };
};

template<class ClassList>
class Simple_Visitor : public Loki::GenLinearHierarchy< ClassList, Noir_Impl::Visit_Unit > { };

0

主题

62

帖子

62

积分

注册会员

Rank: 2

积分
62
发表于 2004-5-8 17:22:00 | 显示全部楼层

Re:简单实现设计模式

Strategy 策略这里可以给出一个简单实现,比如游戏中某个AI有若干套AI,可以定义一个抽象的AI基类,然后其他AI类从他继承。这样只需要一个只向基类的指针,就很容易在运行时改变AI了。

4

主题

42

帖子

42

积分

注册会员

Rank: 2

积分
42
发表于 2004-5-9 16:57:00 | 显示全部楼层

Re: 简单实现设计模式

好文,谢谢

4

主题

714

帖子

714

积分

高级会员

Rank: 4

积分
714
QQ
发表于 2008-4-7 21:44:00 | 显示全部楼层

Re:简单实现设计模式

架构不是功能的要求,却是工程的要求

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
发表于 2008-4-8 01:33:00 | 显示全部楼层

Re:简单实现设计模式

解决了语法问题,
没有解决设计上的问题。

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
发表于 2008-4-8 01:37:00 | 显示全部楼层

Re:简单实现设计模式

这个很有意思:

Observer 观察者:

目的:
为了实现一种一对多的关系,当一个对象发生变化,那么所有依赖他的对象都需要发生变化


这个也不错,但是,实现呢?

Mediator 中介者:

目的:
把对象间的交互抽象出来,这样可减少交互对象之间的偶合,因为偶合被转移到中介者身上

实现:
无固定实现

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
发表于 2008-4-8 01:43:00 | 显示全部楼层

Re:简单实现设计模式

本质上,从纯 C 语言(面向过程)角度来说,这些设计模式问题根本不存在。
所以说基本只是语法问题,而非问题本质。

Mediator 中介者

如果所有类都存在耦合,那么这种设计模式似乎退化为面象过程。
类将变成仅仅是数据成员。

虽然对象之间的耦合不复存在,但是对象根本就只是一些数据了,
所有的交互,全部由Mediator处理。

那么,Mediator按照什么  模式  编码?
它处理了那么多类的复杂交互,总不能硬编码吧。。


33

主题

544

帖子

554

积分

高级会员

Rank: 4

积分
554
发表于 2008-4-8 12:21:00 | 显示全部楼层

Re:简单实现设计模式

个人感觉,那个,这种凭空的而不依赖于项目需求的实现,没多大意义吧~~

0

主题

172

帖子

176

积分

注册会员

Rank: 2

积分
176
发表于 2008-4-8 12:41:00 | 显示全部楼层

Re:简单实现设计模式

设计模式是源自传统工程的思想,是为了更好的总结和概括前人在架构上的设计,它是一种方法,而不是“算法”。

单纯的设计模式没有丝毫意思,只有用在“工程”项目上,根据具体情况使用,才是正道。学习它最精要的莫过于在合适的场合,根据实际工程需要,采用合适的模式(先进、有远见的设计,不见得是你当前项目需要的)

既不要为了模式而模式,也不要看低前人的经验总结,站在巨人肩膀上总是能走得更远。

10

主题

173

帖子

178

积分

注册会员

Rank: 2

积分
178
发表于 2008-4-8 12:50:00 | 显示全部楼层

Re:简单实现设计模式

ace用的好像似乎就是这种模式。使用该库的时候极其方便简单。不过若去研究ace的代码,也需要非一般的耐心。
游戏制作中,策划需求变化莫测,难在于不好规范。如果细致的规范,难显其模式优势;如果范范的规范,难见其模式的优势。
好文,好做法,难于取舍。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-22 21:02

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表