Design Patterns Overview - structural model

The article "Design Patterns Overview - Create schema" finishing the five types of schema creation, and today we went to sort out the structural model.

Structural model is intended to describe how to combine together to form a larger class or object structure. Combination of class-based structural model of concern, and there is generally only achieved inheritance relations; structural model combined object classes and objects of interest, such that the relationship defined by another instance of the object class in a class, and to achieve the object call the method (system we now have a lot of development in this application). Most structural model is an object structural model.

Structural model of a total of seven kinds of specific patterns, respectively, the adapter mode, bridge mode, combination mode, decorative patterns, pattern appearance, Flyweight, proxy mode.

We define and describe the following will look at a few simple structural model.

1. Adapter mode (Adapter Pattern)

Adapter action mode is converted into a form of interface to another form of interface that the interface class can be incompatible with the work, so the adapter also called wrapper. Adapter mode as model class structure, the structure may be used as an object model.

Mode adapter contains four roles:
(1) certain abstract class the Target
(2) Class Adapter Adapter
(. 3) based fitter the Adaptee
(. 4) Customer Client class, or a class of users, i.e. callers.

Sample code:

#include <iostream>
#include "Adapter.h"
#include "Adaptee.h"
#include "Target.h"

using namespace std;

int main(int argc, char *argv[])
{
	Adaptee * adaptee  = new Adaptee();
	Target * tar = new Adapter(adaptee);
	tar->request();
	
	return 0;
}
///////////////////////////////////////////////////////////
//  Adapter.h
//  Definition of the Class Adapter
///////////////////////////////////////////////////////////

#include "Target.h"
#include "Adaptee.h"

class Adapter : public Target
{
public:
	Adapter(Adaptee *adaptee);
	virtual ~Adapter();

	virtual void request();

private:
	Adaptee* m_pAdaptee;

};
///////////////////////////////////////////////////////////
//  Adapter.cpp
//  Implementation of the Class Adapter
///////////////////////////////////////////////////////////

#include "Adapter.h"

Adapter::Adapter(Adaptee * adaptee)
{
	m_pAdaptee =  adaptee;
}

Adapter::~Adapter()
{
}

void Adapter::request()
{
	m_pAdaptee->specificRequest();
}
///////////////////////////////////////////////////////////
//  Adaptee.h
//  Definition of the Class Adaptee
///////////////////////////////////////////////////////////

class Adaptee
{
public:
	Adaptee();
	virtual ~Adaptee();

	void specificRequest();

};

Adapter Model application scenarios:
(1) the system requires the use of an existing class, an interface, which does not meet the needs of the system;
(2) wishes to establish a reusable class for not much correlation between each other work together to organize the class.

2. bridge mode (Bridge Pattern)

Bridge mode is an abstraction partial separation of its implementation, so that the two can be varied independently, also known as the shank member (Handle and Body) mode or an interface (Interface) mode.

Bridge mode contains four roles:
(1) abstract class Abstraction
(2) Extended abstract class RefinedAbstraction
(. 3) interface implementation class the Implementor
(. 4) implementation class ConcreteImplementor

Sample code:

#include <iostream>
#include "ConcreteImplementorA.h"
#include "ConcreteImplementorB.h"
#include "RefinedAbstraction.h"
#include "Abstraction.h"

using namespace std;

int main(int argc, char *argv[])
{
	
	Implementor * pImp = new ConcreteImplementorA();
	Abstraction * pa = new RefinedAbstraction(pImp);
	pa->operation();
	
	Abstraction * pb = new RefinedAbstraction(new ConcreteImplementorB());
	pb->operation();		
	
	delete pa;
	delete pb;
	
	return 0;
}
///////////////////////////////////////////////////////////
//  RefinedAbstraction.h
//  Definition of the Class RefinedAbstraction
///////////////////////////////////////////////////////////

#include "Abstraction.h"

class RefinedAbstraction : public Abstraction
{

public:
	RefinedAbstraction();
	RefinedAbstraction(Implementor* imp);
	virtual ~RefinedAbstraction();

	virtual void operation();

};
///////////////////////////////////////////////////////////
//  RefinedAbstraction.cpp
//  Implementation of the Class RefinedAbstraction
///////////////////////////////////////////////////////////

#include "RefinedAbstraction.h"
#include <iostream>
using namespace std;

RefinedAbstraction::RefinedAbstraction()
{

}

RefinedAbstraction::RefinedAbstraction(Implementor* imp)
	:Abstraction(imp)
{
}

RefinedAbstraction::~RefinedAbstraction()
{

}

void RefinedAbstraction::operation()
{
	cout << "do something else ,and then " << endl;
	m_pImp->operationImp();
}

Bridge mode to understand a certain degree of difficulty. Important is how the abstract model and decoupling of the implement, so that the two can vary independently. Decoupling bridge mode refers to a software abstraction between the system and the realization of, instead of using the inheritance relationship, so that the change in both non-interfering. Imagine a cross-platform video player that can be used in different operating systems such as Windows, Linux, iOS above play different formats of video files such as MP4, AVI, WMV and so on.

3. decorative patterns (Decorator Pattern)

Decorative pattern is an object to dynamically add some additional responsibilities, subject to increase in terms of functionality, decorative pattern is more flexible than a subclass. Decorative patterns and more like adapter mode, but they apply to different scenarios.

Decorative pattern contains four roles:
(1) abstract component the Component
(2) the specific member ConcreteComponent
(. 3) abstract decorative the Decorator
(. 4) particularly decorative ConcreteDecorator

Sample code:

///////////////////////////////////////////////////////////
//  ConcreteComponent.cpp
//  Implementation of the Class ConcreteComponent
///////////////////////////////////////////////////////////

#include "ConcreteComponent.h"
#include <iostream>
using namespace std;

ConcreteComponent::ConcreteComponent()
{

}

ConcreteComponent::~ConcreteComponent()
{

}

void ConcreteComponent::operation()
{
	cout << "ConcreteComponent's normal operation!" << endl;
}
///////////////////////////////////////////////////////////
//  ConcreteDecoratorA.h
//  Definition of the Class ConcreteDecoratorA
///////////////////////////////////////////////////////////

#include "Decorator.h"
#include "Component.h"

class ConcreteDecoratorA : public Decorator
{

public:
	ConcreteDecoratorA(Component* pcmp);
	virtual ~ConcreteDecoratorA();

	void addBehavior();
	virtual void operation();

};
///////////////////////////////////////////////////////////
//  ConcreteDecoratorA.cpp
//  Implementation of the Class ConcreteDecoratorA
///////////////////////////////////////////////////////////

#include "ConcreteDecoratorA.h"
#include <iostream>
using namespace std;

ConcreteDecoratorA::ConcreteDecoratorA(Component* pcmp):Decorator(pcmp)
{

}

ConcreteDecoratorA::~ConcreteDecoratorA()
{

}

void ConcreteDecoratorA::addBehavior()
{
	cout << "addBehavior AAAA" << endl;
}


void ConcreteDecoratorA::operation()
{
	Decorator::operation();
	addBehavior();
}

Compared with the inheritance relationship, not destroy advantage of encapsulation class, is a loosely coupled relationship, especially for system behavior increase in the maintenance phase. Decorator pattern can be dynamically attached to an object's behavior more, without creating more subclass, implement the extended functionality of the object.

4. Appearance Model (Facade Pattern)

Facade appearance model also called model, which provides a consistent level interface (appearance of the object) in the system a set of subsystems, communicating with the outside through these subsystems must be the appearance of the object.

Appearance pattern comprising two roles:
(1) Appearance role the Facade
(2) subsystem role SubSystem

Sample code:

#include <iostream>
#include "Facade.h"
using namespace std;

int main(int argc, char *argv[])
{
	Facade fa;
	fa.wrapOpration();
	
	return 0;
}
///////////////////////////////////////////////////////////
//  Facade.h
//  Definition of the Class Facade
///////////////////////////////////////////////////////////
#ifndef __FACADE_H__
#define __FACADE_H__

#include "SystemC.h"
#include "SystemA.h"
#include "SystemB.h"

class Facade
{

public:
	Facade();
	virtual ~Facade();

	void wrapOpration();

private:
	SystemC *m_SystemC;
	SystemA *m_SystemA;
	SystemB *m_SystemB;
};

#endif
///////////////////////////////////////////////////////////
//  Facade.cpp
//  Implementation of the Class Facade
///////////////////////////////////////////////////////////

#include "Facade.h"


Facade::Facade()
{
	m_SystemA  = new SystemA();
	m_SystemB = new SystemB();
	m_SystemC = new SystemC();
}


Facade::~Facade()
{
	delete m_SystemA;
	delete m_SystemB;
	delete m_SystemC;
}

void Facade::wrapOpration()
{
	m_SystemA->operationA();
	m_SystemB->operationB();
	m_SystemC->opeartionC();
}

By introducing an exterior appearance of the object model, the access subsystem provides a simple and single inlet, thereby reducing the complexity of the original system, the scheduling module to reduce the coupling of the sub-classes, the "Demeter" a reflection. Melody module without concern for the details of the various subsystems of work, you can call the appropriate functions by the appearance of roles.

5. Flyweight (Flaywight Pattern)

Flyweight pattern is the use of shared technical support large numbers of fine-grained object reuse. Systems use only a small number of objects, and these objects are very similar, a small change in state, the object may be achieved by multiplexing a plurality of times. Since Flyweight claim shared objects must be capable of fine-grained objects, and therefore it is called lightweight mode.

Flyweight mode, content can be shared internal state (Intrinsic State), and those contents can not be shared need to set the external environment is referred to as external states (Extrinsic State).

Flyweight contains four roles:
(1) abstract metaclass enjoy the Flyweight
(2) enjoy particularly metaclass ConcreteFlyweight
(. 3) enjoy particularly non-shared metaclass UnsharedConcreteFlyweight
(. 4) Flyweight factory class FltyweightFactory

Sample code:

#include <iostream>
#include "ConcreteFlyweight.h"
#include "FlyweightFactory.h"
#include "Flyweight.h"
using namespace std;

int main(int argc, char *argv[])
{
	FlyweightFactory factory;
	Flyweight * fw = factory.getFlyweight("one");
	fw->operation();
	
	Flyweight * fw2 = factory.getFlyweight("two");
	fw2->operation();
	//aready exist in pool
	Flyweight * fw3 = factory.getFlyweight("one");
	fw3->operation();
	return 0;
}
///////////////////////////////////////////////////////////
//  FlyweightFactory.cpp
//  Implementation of the Class FlyweightFactory
///////////////////////////////////////////////////////////

#include "FlyweightFactory.h"
#include "ConcreteFlyweight.h"
#include <iostream>
using namespace std;

FlyweightFactory::FlyweightFactory()
{

}

FlyweightFactory::~FlyweightFactory()
{

}

Flyweight* FlyweightFactory::getFlyweight(string str)
{
	map<string,Flyweight*>::iterator itr = m_mpFlyweight.find(str);
	
	if(itr == m_mpFlyweight.end())
	{
		Flyweight * fw = new ConcreteFlyweight(str);
		m_mpFlyweight.insert(make_pair(str,fw));
		return fw;	
	}
	else
	{
		cout << "Aready in the pool,use the exist one:" << endl;
		return itr->second;
	}		
}
///////////////////////////////////////////////////////////
//  ConcreteFlyweight.h
//  Definition of the Class ConcreteFlyweight
///////////////////////////////////////////////////////////

#ifndef __CONCRET_FLAYWEIGHT_H__
#define __CONCRET_FLAYWEIGHT_H__

#include "Flyweight.h"
#include <string>
using namespace std;

class ConcreteFlyweight : public Flyweight
{

public:
	ConcreteFlyweight(string str);
	virtual ~ConcreteFlyweight();

	virtual void operation();

private:
	string intrinsicState;

};

#endif
///////////////////////////////////////////////////////////
//  ConcreteFlyweight.cpp
//  Implementation of the Class ConcreteFlyweight
///////////////////////////////////////////////////////////

#include "ConcreteFlyweight.h"
#include <iostream>
using namespace std;


ConcreteFlyweight::ConcreteFlyweight(string str)
{
	intrinsicState = str;
}

ConcreteFlyweight::~ConcreteFlyweight()
{

}

void ConcreteFlyweight::operation()
{
	cout << "Flyweight[" << intrinsicState << "] do operation." << endl; 
}

Flyweight normally occur factory mode, the code can be seen from the above, the plant used to maintain a Flyweight Flyweight pool for storing the internal state of the same shared element object. When the need for an object, first obtain from the pool Flyweight, Flyweight if the pool does not exist, create a new object is returned to the user Flyweight, Flyweight pool and save the new object.

6. Agent Mode (Proxy Pattern)

When the user does not want or can not directly refer to an object may be achieved indirectly through an application called "agent" third party. The operation of the real object is achieved by introducing a new object, the new object is introduced or as a substitute for the real object, which is the mechanism to realize proxy mode.

Proxy mode contains three roles:
(1) abstract role Subject
(2) acting role Proxy
(3) real role RealSubject

Sample code:

#include <iostream>
#include "RealSubject.h"
#include "Proxy.h"

using namespace std;

int main(int argc, char *argv[])
{
	Proxy proxy;
	proxy.request();
	
	return 0;
}
///////////////////////////////////////////////////////////
//  Proxy.h
//  Definition of the Class Proxy
///////////////////////////////////////////////////////////
#ifndef __PROXY_H__
#define __PROXY_H__

#include "RealSubject.h"
#include "Subject.h"

class Proxy : public Subject
{

public:
	Proxy();
	virtual ~Proxy();

	void request();

private:
	void afterRequest();
	void preRequest();	
	RealSubject *m_pRealSubject;

};

#endif
///////////////////////////////////////////////////////////
//  Proxy.cpp
//  Implementation of the Class Proxy
///////////////////////////////////////////////////////////

#include "Proxy.h"
#include <iostream>
using namespace std;

Proxy::Proxy()
{
	m_pRealSubject = new RealSubject();
}

Proxy::~Proxy()
{
	delete m_pRealSubject;
}

void Proxy::afterRequest()
{
	cout << "Proxy::afterRequest" << endl;
}

void Proxy::preRequest()
{
	cout << "Proxy::preRequest" << endl;
}


void Proxy::request()
{
	preRequest();
	m_pRealSubject->request();
	afterRequest();
}

Abstract thematic roles declares the common interface to the real theme and the theme of the agent; internal agency thematic roles included a reference to the real subject, which can operate real theme objects at any time; the real topic roles to achieve real business operations. Users can invoke a method through a proxy thematic roles defined in the role of a real theme indirect. Mode coupling agent may be reduced in the system to some extent.

Common agents are: Remote Agent, Alerts, protection agency, to be a firewall, intelligent agents, and other references.
 

Published 57 original articles · won praise 58 · views 130 000 +

Guess you like

Origin blog.csdn.net/DeliaPu/article/details/104504086