程序设计模式之二

中介模式

中介(Mediator)模式建议,取消彼此独立的组件之间的所有直接通信。这些组件必须通过调用特殊中介对象,以实现间接协作。其结果是,这些组件只依赖于一个中介类,而不是直接把这些组件耦合到一起。

在面向对象的程序设计中,程序通常由许多类组成。这些类之间相互需要交换数据,以实现需要的商务逻辑和计算。然而,随着越来越多的类添加到程序中,这些类之间的通信问题可能变得更加复杂。这使得程序阅读和维护更加困难。因为,任何更改都可能涉及多个类的代码。

中介模式,对象之间的通信被集中在一个中介对象中。对象之间不再直接相互通信,而是通过中介进行通信。这减少了通信对象之间的依赖关系,从而减少了耦合。

中介模式应该满足下列的要求

  • 避免一组交互对象之间的紧密耦合。
  • 可以独立地改变一组对象之间的交互。

中介模式就是定义一个单独的对象(中介),将对象之间的交互作用,封装在这个中介中。这些对象将它们的交互委托给中介对象,而不是直接交互。

#include	<iostream>
#include    <string>
#include	<map>
#include 	<memory>

using namespace std;

template <class T> class Mediator;

template <class T>
class Storage {
    T value;
    
    T getValue() {
        return value;
    }
public:
    void setValue(Mediator<T> *mediator, string storageName, T value) {
        this->value = value;
        mediator->notifyObservers(storageName);
    }
};

class Observer {
public:
	virtual void execute() = 0;
};

class Observer1 : public Observer
{
public:
	void execute(){
		cout << "observer 1" << endl;
	}
};

template <class T>
class Mediator {
private:
	map<string, shared_ptr<Storage<T>>> storageMap;
	map<string, shared_ptr<Observer>> observers;
	
public:
	void setValue(string storageName, T value) {
        auto it = storageMap.find(storageName);
		shared_ptr<Storage<T>> st;
		
		if (it == storageMap.end())
		{
			st = make_shared<Storage<T>>();
			storageMap[storageName] = st;
		}
		else {
			st = (it->second);
		}
		st->setValue(this, storageName, value);
    }

    T getValue(string storageName) {
		Storage<T> st = storageMap.get(storageName);
        return st.getValue();
    }
    
    void addObserver(string storageName, shared_ptr<Observer> observer) {
		observers[storageName] = observer;
    }
  
    void notifyObservers(string eventName) {
		map<string, shared_ptr<Observer>> ::iterator it;
		
		it = observers.find(eventName);
		if (it == observers.end())
			return;
			
		shared_ptr<Observer> p = it->second;
		cout << it->first << ":";
			
		p->execute();
    }
};

int main() {
	
    Mediator<int> mediator;
    mediator.setValue("bob", 20);
    mediator.setValue("alice", 24);
    mediator.setValue("jason", 16);
    
	shared_ptr<Observer1> ob1 = make_shared<Observer1>();
	shared_ptr<Observer> obptr = static_cast<shared_ptr<Observer>>(ob1);
    mediator.addObserver("bob", obptr);	
    mediator.setValue("bob", 21);
	
    mediator.setValue("alice", 26);

    mediator.addObserver("jason", obptr);	
    mediator.setValue("jason", 21);
}

输出结果

bob:observer 1
jason:observer 1

观察者模式

观察者模式是一种软件设计模式,在这个模式中,一个对象(称为主体)维护一组依赖项,这些依赖项也被称为观察者,通常,通过调用它们的方法之一,自动通知它们任何状态更改。

它主要用于在“事件驱动”软件设计中,实现分布式事件处理系统。在这些系统中,主体通常被称为“事件流”或“事件流源”,而观察者被称为“事件接收器”。
这种模式非常适合任何进程,在启动时CPU不知道数据输入何时到达,它们是“随机”到达,比如,HTTP 请求、GPIO 数据、来自键盘/鼠标的用户输入都属于这种类型。大多数现代程序设计语言都包含实现观察者模式组件的内置“事件”结构。
大多数“观察者”实现,使用后台线程,监听主体事件。

#include  <iostream>
#include  <vector>
#include  <memory>

using  namespace std;

class Observer {
public:
	Observer()=default;
    virtual void update(string event)=0;
};

class Observer1 : public Observer {
public:
	Observer1()=default;
    virtual void update(string event) override
    {
		cout << "Observer1: " << event << endl;
    }
};

class Observer2 : public Observer {
public:
	Observer2()=default;
    virtual void update(string event) override
    {
		cout << "Observer2: " << event << endl;
    }
};

class EventSource {
  
private:
	vector<Observer *> observers;
  
	void notifyObservers(string event) {
		for (auto observer : observers)
            observer->update(event);
    }
 
public: 
    void addObserver(Observer *observer) {
        observers.push_back(observer);
    }
  
    void deliver_cmd(vector<string> cmds) {
        for (auto cmd : cmds) {
            notifyObservers(cmd);
        }
    }
};

int main()
{
    shared_ptr<EventSource> eventSource = make_shared<EventSource>();
    Observer  *ob1 = new Observer1();
    eventSource->addObserver(ob1);
    Observer  *ob2 = new Observer2();
    eventSource->addObserver(ob2);

	vector<string> v1 = {"start", "pause", "stop"};
    eventSource->deliver_cmd(v1);
	
	delete ob1;
	delete ob2;
}

输出结果

Observer1: start
Observer2: start
Observer1: pause
Observer2: pause
Observer1: stop
Observer2: stop

代理模式

代理(proxy)模式是一种软件设计模式。代理是一个充当其他事物接口的类。代理可以连接到任何东西:网络连接、内存中的大对象、文件或其他一些昂贵或无法复制的资源。
简而言之,代理是一个包装器或代理对象,客户端通过它来访问幕后的提供真实服务的对象。使用代理可以简单地转发到真实对象,或者可以提供额外的逻辑。
代理可以提供额外的功能,例如提供缓存,或者在调用真实对象上的操作之前,检查先决条件。对于客户端,使用代理对象与使用真实对象类似,因为两者都实现了相同的接口。

#include	<iostream>
#include	<memory>
#include	<map>

using namespace  std;

class Image {
public:
	virtual void displayImage() = 0;
};

class RealImage : public Image {
private:
	string filename;

public:
	RealImage(string filen) {
        filename = filen;
        loadImageFromDisk();
    }

	void loadImageFromDisk() {
        cout << "Loading   " << filename << endl;
    }

	void displayImage() {
        cout << "Displaying " << filename << endl;
    }
};

class Imagebufs {
public:
	static shared_ptr<Imagebufs> m_Inst;
	
	static shared_ptr<Imagebufs> getInstance() {
		if  (m_Inst == nullptr)
			m_Inst = make_shared<Imagebufs>();
		return m_Inst;
	}
	
	shared_ptr<RealImage> get_realimage(string image)
	{
		map<string, shared_ptr<RealImage>>::iterator it;
		it = imgbufs.find(image);
		
		if (it == imgbufs.end())
			return nullptr;
		return it->second;
	}

	void put_realimage(string fn, shared_ptr<RealImage> image)
	{
		imgbufs[fn] = image;
	}
	
private:
	map<string, shared_ptr<RealImage>>  imgbufs;
};

shared_ptr<Imagebufs> Imagebufs::m_Inst=nullptr;

class ProxyImage : public Image {
private:
	string filename;
    shared_ptr<RealImage> image = nullptr;
    
public:
	ProxyImage(string filen) {
        filename = filen;
    }

    void displayImage() {
		shared_ptr<Imagebufs> bufs = Imagebufs::getInstance();
		
		image = bufs->get_realimage(filename);		
        if (image == nullptr) {
           image = make_shared<RealImage>(filename);
		   bufs->put_realimage(filename, image);
        }
		
        image->displayImage();
    }
};

int main() {
    shared_ptr<Image> image1 = make_shared<ProxyImage>("HiRes_10MB_Photo1");
    shared_ptr<Image> image2 = make_shared<ProxyImage>("HiRes_10MB_Photo2");
    shared_ptr<Image> image3 = make_shared<ProxyImage>("HiRes_10MB_Photo2");

    image1->displayImage(); // loading 
    image1->displayImage(); // no loading
    image2->displayImage(); // loading
    image2->displayImage(); // no loading
    image1->displayImage(); // no loading
	
    image3->displayImage(); // no loading
}

输出结果

Loading   HiRes_10MB_Photo1
Displaying HiRes_10MB_Photo1
Displaying HiRes_10MB_Photo1
Loading   HiRes_10MB_Photo2
Displaying HiRes_10MB_Photo2
Displaying HiRes_10MB_Photo2
Displaying HiRes_10MB_Photo1
Displaying HiRes_10MB_Photo2

仆人模式

在软件工程中,仆人(Servant )模式定义一个对象,并将它用于向一组类提供某些功能,而无需在每个类中定义该功能。 仆人是一个类,它的实例(甚至只是类)提供处理所需服务的方法,而仆人为其(或与谁)做某事的对象被视为参数。

我们有几个类表示几何对象(椭圆和三角形)。我们可以在一些画布上绘制这些对象。当我们需要为这些对象提供“移动”方法时,我们可以在每个类中实现这个方法,或者我们可以定义一个接口,在仆人中提供“移动”功能。定义这个接口,是为了确保被服务的对象提供仆人所需行为的方法,以便完成所需的移动功能。

我们定义一个接口“IMovable”,指定被服务的对象都需要实现的方法“getPosition”和“setPosition”。第一个方法获取对象在画布上的位置,第二个方法设置对象的位置,并将其绘制在画布上。
然后我们定义了一个仆人类“MoveServant”,它有两个方法“moveTo(Object, where)”和moveBy(Object, int dx, int dy)。

#include	<iostream>
#include	<memory>

using namespace std;

class Point {
public:
	Point() : x(0), y(0){};
	Point(int xv, int yv) : x(xv), y(yv){};
	
	int  x;
	int  y;
};

class IMovable {
public:
	virtual void setPosition(Point p)=0;
	virtual Point getPosition()=0; 
};

class Triangle : public IMovable {
	Point position;
 
public:
	Triangle(int x, int y) {
		position.x = x;
		position.y = y;
	}
	
	void setPosition(Point p) {
		position = p;
	}

	Point getPosition() {
		return position;
	}
};

class Ellipse : public IMovable {
private:
	Point p;

public:
	Ellipse(int x, int y) {
		p.x = x;
		p.y = y;
	}
	
	void setPosition(Point pv) {
		p = pv;
	}

	Point getPosition() {
		return p;
	}
};

class MoveServant {
public: 
	MoveServant()=default;
	void moveTo(shared_ptr<IMovable> moved, Point pt){
		Point pt2 = moved->getPosition();
		cout << "Moving from (" << pt2.x << "," << pt2.y << ") to (" 
		     << pt.x << "," << pt.y << ")" << endl;		
		moved->setPosition(pt);
	}
 
	void moveBy(shared_ptr<IMovable> moved, int x, int y){
		Point pt = moved->getPosition();
		cout << "Moving from (" << pt.x << "," << pt.y << ") to (" 
		     << pt.x + x << "," << pt.y + y << ")" << endl;		
		moved->setPosition(Point(pt.x + x, pt.y + y));
	}
};

int main () {
	shared_ptr<MoveServant> servant = make_shared<MoveServant>();
	
	shared_ptr<Triangle> triangle = make_shared<Triangle>(-1,0);
	shared_ptr<Ellipse> ellipse = make_shared<Ellipse>(2,5);

	servant->moveBy(ellipse, 2, 4);
	servant->moveTo(triangle, Point(-4,0));
}

输出结果

Moving from (2,5) to (4,9)
Moving from (-1,0) to (-4,0)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值