工厂模式
工厂模式class Product{ public: virtual ~Product() = 0; protected: Product();//屏蔽构造函数, 浅拷贝问题,自定义了基类和派生类的拷贝构造函数,但派生类对象拷贝时,调用了派生类的拷贝,没有调用自定义的基类拷贝而是调用默认的基类拷贝。 private: }; class ConcreteProduct:: public Product{ public: ~ConcreteProduct(); ConcreteProduct(); protected: private: }; class Factory{ public: virtual ~Factory() = 0; virtual Product* CreateRroduct() = 0; protected: Factory(); private: }; class ConcreteFactory:public Factory{ public: ~ConcreteFactory(); ConcreteFactory(); Product* CreateRroduct(); protected: private: }; Product* ConcreteFactory::CreateProduct() { return new ConcreteProduct(); } 代
- Factory模式解决父类中并不知道具体要实例化哪一个具体的子类的问题,至于为创建对象提供接口问题,可以由Factory中附加相应的创建 *** 作例如Create***Product()
class AbstractProductA { public: virtual ~AbstractProductA(); protected: AbstractProductA(); private: }; class AbstractProductB { public: virtual ~AbstractProductB(); protected: AbstractProductB(); private: }; class ProductA1:public AbstractProductA { public: ProductA1(); ~ProductA1(); protected: private: }; class ProductA2:public AbstractProductA { public: ProductA2(); ~ProductA2(); protected: private: }; class ProductB1:public AbstractProductB { public: ProductB1(); ~ProductB1(); protected: private: }; class ProductB2:public AbstractProductB { public: ProductB2(); ~ProductB2(); protected: private: }; class AbstractFactory { public: virtual ~AbstractFactory(); virtual AbstractProductA* CreateProductA() = 0; virtual AbstractProductB* CreateProductB() = 0; protected: AbstractFactory(); private: }; class ConcreteFactory1:public AbstractFactory { public: ConcreteFactory1(); ~ConcreteFactory1(); AbstractProductA* CreateProductA(); AbstractProductB* CreateProductB(); protected: private: }; class ConcreteFactory2:public AbstractFactory { public: ConcreteFactory2(); ~ConcreteFactory2(); AbstractProductA* CreateProductA(); AbstractProductB* CreateProductB(); protected: private: };
- AbstractFactory模式和Factory模式的区别是初学(使用)设计模式时候的一个容易引起困惑的地方。实际上,AbstractFactory模式是为创建一组(有多类)相关或依赖的对象提供创建接口,而Factory模式正如我在相应的文档中分析的是为一类对象提供创建接口或延迟对象的创建到子类中实现。并且可以看到,AbstractFactory模式通常都是使用Factory模式实现(ConcreteFactory1)。
class Singleton { public: static Singleton* Instance(); protected: Singleton(); private: static Singleton* _instance; }; Singleton* Singleton::_instance = 0; Singleton* Singleton::Instance() { if (_instance == 0) { _instance = new Singleton(); } return _instance; }
- Singleton模式的实现无须补充解释,需要说明的是,Singleton不可以被实例化,因此我们将其构造函数声明为protected或者直接声明为private。
- 在Singleton模式的结构图中可以看到,我们通过维护一个static的成员变量来记录这
个唯一的对象实例。通过提供一个staitc的接口instance来获得这个唯一的实例。
Java 懒汉式 多线程不安全
public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
Java 饿汉式 多线程安全 产生垃圾对象
public class Singleton { private static Singleton instance = new Singleton(); private Singleton (){} public static Singleton getInstance() { return instance; } }Builder模式(生成器模型)
class Product { public: Product(); ~Product(); void ProducePart(); protected: private: }; class ProductPart { public: ProductPart(); ~ProductPart(); ProductPart* BuildPart(); protected: private: }; ProductPart* ProductPart::BuildPart() { return new ProductPart; } class Builder { public: virtual ~Builder(); virtual void BuildPartA(const string& buildPara) = 0; virtual void BuildPartB(const string& buildPara) = 0; virtual void BuildPartC(const string& buildPara) = 0; virtual Product* GetProduct() = 0; protected: Builder(); private: }; class ConcreteBuilder:public Builder { public: ConcreteBuilder(); ~ConcreteBuilder(); void BuildPartA(const string& buildPara); void BuildPartB(const string& buildPara); void BuildPartC(const string& buildPara); Product* GetProduct(); protected: private: };
- Builder模式和AbstractFactory模式在功能上很相似,因为都是用来创建大的复杂的对象,它们的区别是:Builder模式强调的是一步步创建对象,并通过相同的创建过程可以获得不同的结果对象,一般来说Builder模式中对象不是直接返回的。而在AbstractFactory模式中对象是直接返回的,AbstractFactory模式强调的是为创建多个相互依赖的对象提供一个同一的接口。
class Prototype { public: virtual ~Prototype(); virtual Prototype* Clone() const = 0;//拷贝构造函 protected: Prototype(); private: }; class ConcretePrototype:public Prototype { public: ConcretePrototype(); ConcretePrototype(const ConcretePrototype& cp); ~ConcretePrototype(); Prototype* Clone() const; protected: private: };
- Prototype模式通过复制原型(Prototype)而获得新对象创建的功能,这里Prototype本身就是“对象工厂”(因为能够生产对象),实际上Prototype模式和Builder模式、AbstractFactory模式都是通过一个类(对象实例)来专门负责对象的创建工作(工厂对象),它们之间的区别是:Builder模式重在复杂对象的一步步创建(并不直接返回对象),AbstractFactory模式重在产生多个相互依赖类的对象,而Prototype模式重在从自身复制自己创建新类。
class Abstraction { public: virtual ~Abstraction(); virtual void Operation() = 0; protected: Abstraction(); private: }; class RefinedAbstraction:public Abstraction { public: RefinedAbstraction(AbstractionImp* imp); ~RefinedAbstraction(); void Operation(); protected: private: AbstractionImp* _imp; }; void RefinedAbstraction::Operation() { _imp->Operation(); } class AbstractionImp { public: virtual ~AbstractionImp(); virtual void Operation() = 0; protected: AbstractionImp(); private: }; class ConcreteAbstractionImpA:public AbstractionImp { public: ConcreteAbstractionImpA(); ~ConcreteAbstractionImpA(); virtual void Operation(); protected: private: };
- 上面使用Bridge模式和使用带来问题方式的解决方案的根本区别在于是通过继承还是通过组合的方式去实现一个功能需求。
class Target { public: Target(); virtual ~Target(); virtual void Request(); protected: private: }; class Adaptee { public: Adaptee(); ~Adaptee(); void SpecificRequest(); protected: private: }; void Adapter::Request() { this->SpecificRequest(); } class Adapter:public Target,private Adaptee { public: Adapter(); ~Adapter(); void Request(); protected: private: };
- 接口继承和实现继承是面向对象领域的两个重要的概念,接口继承指的是通过继承,子类获得了父类的接口,而实现继承指的是通过继承子类获得了父类的实现(并不统共接口)。在C++中的public继承既是接口继承又是实现继承,因为子类在继承了父类后既可以对外提供父类中的接口 *** 作,又可以获得父类的接口实现。当然我们可以通过一定的方式和技术模拟单独的接口继承和实现继承,例如我们可以通过private继承获得实现继承的效果(private继承后,父类中的接口都变为private,当然只能是实现继承了。),通过纯抽象基类模拟接口继承的效果,但是在C++中pure virtual function也可以提供默认实现,因此这是不纯正的接口继承,但是在Java中我们可以interface来获得真正的接口继承了。
class Component { public: virtual ~Component(); virtual void Operation(); protected: Component(); private: }; class ConcreteComponent:public Component { public: ConcreteComponent(); ~ConcreteComponent(); void Operation(); protected: private: }; class Decorator:public Component { public: Decorator(Component* com); virtual ~Decorator(); void Operation(); protected: Component* _com; private: }; Decorator::~Decorator() { delete _com; } Decorator::Decorator(Component* com) { this->_com = com; } class ConcreteDecorator:public Decorator { public: ConcreteDecorator(Component* com); ~ ConcreteDecorator(); void Operation(); void AddedBehavior(); protected: private: }; void ConcreteDecorator::Operation() { _com->Operation(); this->AddedBehavior(); }
- Decorator模式除了采用组合的方式取得了比采用继承方式更好的效果,Decorator模式还给设计带来一种“即用即付”的方式来添加职责。在OO设计和分析经常有这样一种情况:为了多态,通过父类指针指向其具体子类,但是这就带来另外一个问题,当具体子类要添加新的职责,就必须向其父类添加一个这个职责的抽象接口,否则是通过父类指针是调用不到这个方法了。这样处于高层的父类就承载了太多的特征(方法),并且继承自这个父类的所有子类都不可避免继承了父类的这些接口,但是可能这并不是这个具体子类所需要的。而在Decorator模式提供了一种较好的解决方法,当需要添加一个 *** 作的时候就可以通过Decorator模式来解决,你可以一步步添加新的职责。
class Component { public: Component(); virtual ~Component(); public: virtual void Operation() = 0; virtual void Add(const Component& ); virtual void Remove(const Component& ); virtual Component* GetChild(int ); protected: private: }; class Composite:public Component { public: Composite(); ~Composite(); public: void Operation(); void Add(Component* com); void Remove(Component* com); Component* GetChild(int index); protected: private: vectorcomVec; }; void Composite::Operation() { vector ::iterator comIter = comVec.begin(); for (;comIter != comVec.end();comIter++) { (*comIter)->Operation(); } } class Leaf:public Component { public: Leaf(); ~Leaf(); void Operation(); protected: private: };
- Composite模式在实现中有一个问题就是要提供对于子节点(Leaf)的管理策略,这里使用的是STL中的vector,可以提供其他的实现方式,如数组、链表、Hash表等。Composite模式通过和Decorator模式有着类似的结构图,但是Composite模式旨在构造类,而Decorator模式重在不生成子类即可给对象添加职责。Decorator模式重在修饰,而Composite模式重在表示。
class Flyweight { public: virtual ~Flyweight(); virtual void Operation(const string& extrinsicState); string GetIntrinsicState(); protected: Flyweight(string intrinsicState); private: string _intrinsicState; }; class ConcreteFlyweight:public Flyweight { public: ConcreteFlyweight(string intrinsicState); ~ConcreteFlyweight(); void Operation(const string& extrinsicState); protected: private: }; class FlyweightFactory { public: FlyweightFactory(); ~FlyweightFactory(); Flyweight* GetFlyweight(const string& key); protected: private: vector_fly; };
- Flyweight模式在实现过程中主要是要为共享对象提供一个存放的“仓库”(对象池),这里是通过C++ STL中Vector容器,当然就牵涉到STL编程的一些问题(Iterator使用等)。另外应该注意的就是对对象“仓库”(对象池)的管理策略(查找、插入等),这里是通过直接的顺序遍历实现的,当然我们可以使用其他更加有效的索引策略,例如Hash表的管理策略,当时这些细节已经不是Flyweight模式本身要处理的了。
class Subsystem1{ public: Subsystem1(); ~Subsystem1(); void Operation(); protected: private: }; class Subsystem2{ public: Subsystem2(); ~Subsystem2(); void Operation(); protected: private: }; class Facade{ public: Facade(); ~Facade(); void OperationWrapper(); protected: private: Subsystem1* _subs1; Subsystem2* _subs2; };
- Façade模式在高层提供了一个统一的接口,解耦了系统。设计模式中还有另一种模式Mediator也和Façade有类似的地方。但是Mediator主要目的是对象间的访问的解耦(通讯时候的协议),具体请参见Mediator文档。
class Subject { public: virtual ~Subject(); virtual void Request() = 0; protected: Subject(); private: }; class ConcreteSubject:public Subject { public: ConcreteSubject(); ~ConcreteSubject(); void Request(); protected: private: }; class Proxy { public: Proxy(); Proxy(Subject* sub); ~Proxy(); void Request(); protected: private: Subject* _sub; }; Proxy::~Proxy() { delete _sub; }
- Proxy模式最大的好处就是实现了逻辑和实现的彻底解耦。
class AbstractClass { public: virtual ~AbstractClass(); void TemplateMethod(); protected: virtual void PrimitiveOperation1() = 0; virtual void PrimitiveOperation2() = 0; AbstractClass(); private: }; class ConcreteClass1:public AbstractClass { public: ConcreteClass1(); ~ConcreteClass1(); protected: void PrimitiveOperation1(); void PrimitiveOperation2(); private: }; void AbstractClass::TemplateMethod() { this->PrimitiveOperation1(); this->PrimitiveOperation2(); }
- Template模式获得一种反向控制结构效果,这也是面向对象系统的分析和设计中一个原则DIP(依赖倒置:Dependency Inversion Principles)。其含义就是父类调用子类的 *** 作(高层模块调用低层模块的 *** 作),低层模块实现高层模块声明的接口。这样控制权在父类(高层模块),低层模块反而要依赖高层模块。
class Strategy { public: Strategy(); virtual ~Strategy(); virtual void AlgrithmInterface() = 0; protected: private: }; class ConcreteStrategyA:public Strategy { public: ConcreteStrategyA(); virtual ~ConcreteStrategyA(); void AlgrithmInterface(); protected: private: }; class ConcreteStrategyB:public Strategy { public: ConcreteStrategyB(); virtual ~ConcreteStrategyB(); void AlgrithmInterface(); protected: private: };
-
Strategy模式和Template模式实际是实现一个抽象接口的两种方式:继承和组合之间的区别。要实现一个抽象接口,继承是一种方式:我们将抽象接口声明在基类中,将具体的实现放在具体子类中。组合(委托)是另外一种方式:我们将接口的实现放在被组合对象中,将抽象接口放在组合类中。
-
继承优点:易于修改和拓展那些被复用的实现,缺点:破坏了封装性,白盒复用,父类改变,而子类也会改变
-
组合优点:黑盒复用,内部细节对外不可见,封装好,可以在运行期间动态定义实现;缺点:对象多
class State { public: State(); virtual ~State(); virtual void OperationInterface(Context* ) = 0; virtual void OperationChangeState(Context*) = 0; protected: bool ChangeState(Context* con,State* st); private: //bool ChangeState(Context* con,State* st); }; class ConcreteStateA:public State { public: ConcreteStateA(); virtual ~ConcreteStateA(); virtual void OperationInterface(Context* ); virtual void OperationChangeState(Context*); protected: private: }; class ConcreteStateB:public State { public: ConcreteStateB(); virtual ~ConcreteStateB(); virtual void OperationInterface(Context* ); virtual void OperationChangeState(Context*); protected: private: }; { public: Context(); Context(State* state); ~Context(); void OprationInterface(); void OperationChangState(); protected: private: friend class State; //表明在State类中可以访问Context类的private字段 bool ChangeState(State* state); private: State* _state; };
- 将State声明为Context的友元类(friend class),其作用是让State模式访问Context的protected接口ChangeSate()。State及其子类中的 *** 作都将Context传入作为参数,其主要目的是State类可以通过这个指针调用Context中的方法(在本示例代码中没有体现)。这也是State模式和Strategy模式的最大区别所在。State及其子类中的 *** 作都将Context传入作为参数,其主要目的是State类可以通过这个指针调用Context中的方法(在本示例代码中没有体现)。这也是State模式和Strategy模式的最大区别所在。
class Subject { public: virtual ~Subject(); virtual void Attach(Observer* obv); virtual void Detach(Observer* obv); virtual void Notify(); virtual void SetState(const State& st) = 0; virtual State GetState() = 0; protected: Subject(); private: list* _obvs; }; class ConcreteSubject:public Subject { public: ConcreteSubject(); ~ConcreteSubject(); State GetState(); void SetState(const State& st); protected: private: State _st; }; class Observer { public: virtual ~Observer(); virtual void Update(Subject* sub) = 0; virtual void PrintInfo() = 0; protected: Observer(); State _st; private: }; class ConcreteObserverA:public Observer { public: virtual Subject* GetSubject(); ConcreteObserverA(Subject* sub); virtual ~ConcreteObserverA(); //传入Subject作为参数,这样可以让一个View属于多个的Subject。void Update(Subject* sub); void PrintInfo(); protected: private: Subject* _sub; };
- 在Observer模式的实现中,Subject维护一个list作为存储其所有观察者的容器。目标的状态state可以由Subject自己改变(示例),也可以由Observer的某个 *** 作引起state的改变(可调用Subject的SetState *** 作)。
class Memento{ public: protected: private: friend class Originator; typedef string State; Mementor(); Mementor(const State&sdt); ~Memento(); void SetState(const State& sdt) State GetState(); State _sdt; } class Originator{ public: typedef string State; Originator(); Originator(const State& sdt); ~Originator(); Memento* CreateMemento(); void SetMemento(Memento* men); void RestoreToMemento(Memento* mt); State GetState(); void SetState(const State& sdt); void PrintState(); protected: private: State _sdt; Memento* _mt; };
- Memento模式的关键就是friend class Originator;我们可以看到,Memento的接口都声明为private,而将Originator声明为Memento的友元类。我们将Originator的状态保存在Memento类中,而将Memento接口private起来,也就达到了封装的功效。
在Originator类中我们提供了方法让用户后悔:RestoreToMemento(Memento* mt);我们可以通过这个接口让用户后悔。在测试程序中,我们演示了这一点:Originator的状态由old变为new最后又回到了old。
class Colleage { public: virtual ~Colleage(); virtual void Aciton() = 0; virtual void SetState(const string& sdt) = 0; virtual string GetState() = 0; protected: Colleage(); Colleage(Mediator* mdt); Mediator* _mdt; private: }; class ConcreteColleageA:public Colleage { public: ConcreteColleageA(); ConcreteColleageA(Mediator* mdt); ~ConcreteColleageA(); void Aciton(); void SetState(const string& sdt); string GetState(); protected: private: string _sdt; }; class ConcreteColleageB:public Colleage { public: ConcreteColleageB(); ConcreteColleageB(Mediator* mdt); ~ConcreteColleageB(); void Aciton(); void SetState(const string& sdt); string GetState(); protected: private: string _sdt; }; class Mediator { public: virtual ~Mediator(); virtual void DoActionFromAtoB() = 0; virtual void DoActionFromBtoA() = 0; protected: Mediator(); private: }; class ConcreteMediator:public Mediator { public: ConcreteMediator(); ConcreteMediator(Colleage* clgA,Colleage* clgB); ~ConcreteMediator(); void SetConcreteColleageA(Colleage* clgA); void SetConcreteColleageB(Colleage* clgB); Colleage* GetConcreteColleageA(); Colleage* GetConcreteColleageB(); void IntroColleage(Colleage* clgA,Colleage* clgB); void DoActionFromAtoB(); void DoActionFromBtoA(); protected: private: Colleage* _clgA; Colleage* _clgB; };
- Mediator模式的实现关键就是将对象Colleague之间的通信封装到一个类种单独处理,为了模拟Mediator模式的功能,这里给每个Colleague对象一个string型别以记录其状态,并通过状态改变来演示对象之间的交互和通信。Mediator模式是一种很有用并且很常用的模式,它通过将对象间的通信封装到一个类中,将多对多的通信转化为一对多的通信,降低了系统的复杂性。Mediator还获得系统解耦的特性,通过Mediator,各个Colleague就不必维护各自通信的对象和通信协议,降低了系统的耦合性,Mediator和各个Colleague就可以相互独立地修改了。
class Reciever { public: Reciever(); ~Reciever(); void Action(); protected: private: }; class Command { public: virtual ~Command(); virtual void Excute() = 0; protected: Command(); private: }; class ConcreteCommand:public Command { public: ConcreteCommand(Reciever* rev); ~ConcreteCommand(); void Excute(); protected: private: Reciever* _rev; }; class Invoker { public: Invoker(Command* cmd); ~Invoker(); void Invoke(); protected: private: Command* _cmd; };
- Command模式在实现的实现和思想都很简单,其关键就是将一个请求封装到一个类中(Command),再提供处理对象(Receiver),最后Command命令由Invoker激活。另外,我们可以将请求接收者的处理抽象出来作为参数传给Command对象,实际也就是回调的机制(Callback)来实现这一点,也就是说将处理 *** 作方法地址(在对象内部)通过参数传递给Command对象,Command对象在适当的时候(Invoke激活的时候)再调用该函数
class Visitor { public: virtual ~Visitor(); virtual void VisitConcreteElementA(Element* elm) = 0; virtual void VisitConcreteElementB(Element* elm) = 0; protected: Visitor(); private: }; class ConcreteVisitorA:public Visitor { public: ConcreteVisitorA(); virtual ~ConcreteVisitorA(); virtual void VisitConcreteElementA(Element* elm); virtual void VisitConcreteElementB(Element* elm); protected: private: }; class Element { public: virtual ~Element(); virtual void Accept(Visitor* vis) = 0; protected: Element(); private: }; class ConcreteElementA:public Element { public: ConcreteElementA(); ~ConcreteElementA(); void Accept(Visitor* vis); protected: private: };
- 破坏了封装性。Visitor模式要求Visitor可以从外部修改Element对象的状态,这一般通过两个方式来实现:a)Element提供足够的public接口,使得Visitor可以通过调用这些接口达到修改Element状态的目的;b)Element暴露更多的细节给Visitor,或者让Element提供public的实现给Visitor(当然也给了系统中其他的对象),或者将Visitor声明为Element的friend类,仅将细节暴露给Visitor。但是无论那种情况,特别是后者都将是破坏了封装性原则(实际上就是C++的friend机制得到了很多的面向对象专家的诟病)。
class Handle { public: virtual ~Handle(); virtual void HandleRequest() = 0; void SetSuccessor(Handle* succ); Handle* GetSuccessor(); protected: Handle(); Handle(Handle* succ); private: Handle* _succ; }; class ConcreteHandleA:public Handle { public: ConcreteHandleA(); ~ConcreteHandleA(); ConcreteHandleA(Handle* succ); void HandleRequest(); protected: private: };
- Chain of Responsibility模式的最大的一个有点就是给系统降低了耦合性,请求的发送者完全不必知道该请求会被哪个应答对象处理,极大地降低了系统的耦合性。
class Aggregate { public: virtual ~Aggregate(); virtual Iterator* CreateIterator() = 0; virtual Object GetItem(int idx) = 0; virtual int GetSize() = 0; protected: Aggregate(); private: }; class ConcreteAggregate:public Aggregate { public: enum {SIZE = 3}; ConcreteAggregate(); ~ConcreteAggregate(); Iterator* CreateIterator(); Object GetItem(int idx); int GetSize(); protected: private: Object _objs[SIZE]; };
- Iterator模式的实现代码很简单,实际上为了更好地保护Aggregate的状态,我们可以尽量减小Aggregate的public接口,而通过将Iterator对象声明位Aggregate的友元来给予Iterator一些特权,获得访问Aggregate私有数据和方法的机会。
class Context { public: Context(); ~Context(); protected: private: }; class Abstractexpression { public: virtual ~Abstractexpression(); virtual void Interpret(const Context& c); protected: Abstractexpression(); private: }; class Terminalexpression:public Abstractexpression { public: Terminalexpression(const string& statement); ~ Terminalexpression(); void Interpret(const Context& c); protected: private: string _statement; }; class Nonterminalexpression:public Abstractexpression { public: Nonterminalexpression(Abstractexpression* expression,int times); ~ Nonterminalexpression(); void Interpret(const Context& c); protected: private: Abstractexpression* _expression; int _times; };
- XML格式的数据解析是一个在应用开发中很常见并且有时候是很难处理的事情,虽然目前很多的开发平台、语言都提供了对XML格式数据的解析,但是例如到了移动终端设备上,由于处理速度、计算能力、存储容量的原因解析XML格式的数据却是很复杂的一件事情,最近也提出了很多的移动设备的XML格式解析器,但是总体上在项目开发时候还是需要自己去设计和实现这一个过程
电子版资源pdf私聊
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)