• 结构型设计模式- C++实现


    目录

    结构型模式

    代理模式

    Abstract

    Role

    Demo

    装饰模式

    Abstract

    Demo

    适配器模式

    Abstract

    Demo

    组合模式

    Abstract

    Role

    Demo

    桥接模式 bridge

    Abstract

    Role

    Demo

    外观模式 facade

    Abstract

    Role

    Demo

    享元模式flyweight

    Abstract

    Role

    Demo


    结构型模式

    结构型模式主要包括代理模式、装饰模式、适配器模式、组合模式、桥接模式、外观模式、享元模式。

    代理模式

    Abstract

    Proxy模式又叫做代理模式,是构造型的设计模式之一,它可以为其他对象提供一种代理(Proxy)以控制对这个对象的访问。

    所谓代理,是指具有与代理元(被代理的对象)具有相同的接口的类,客户端必须通过代理与被代理的目标类交互,而代理一般在交互的过程中(交互前后),进行某些特别的处理。

    Role

    subject(抽象主题角色):

    真实主题与代理主题的共同接口。

    RealSubject(真实主题角色):

    定义了代理角色所代表的真实对象。

    Proxy(代理主题角色):

    含有对真实主题角色的引用,代理角色通常在将客户端调用传递给真是主题对象之前或者之后执行某些操作,而不是单纯返回真实的对象。

    适合于:

    为其他对象提供一种代理以控制对这个对象的访问

    Demo

    #include 
    #include 
    using namespace std;
    //定义接口
    class Interface
    {
    public:
    	virtual void Request()=0;
    };
    //真实类
    class RealClass : public Interface
    {
    public:
    	virtual void Request()
    	{
    		cout<<"真实的请求"<Request();
    		delete m_realClass;
    	}
    };
    
    
    int main()
    {
    	ProxyClass* test=new ProxyClass();
    	test->Request();
    	return 0;
    }

    装饰模式

    Abstract

    装饰(Decorator )模式又叫做包装模式。通过一种对客户端透明的方式来扩展对象的功能,是继承关系的一个替换方案。

    装饰模式就是把要添加的附加功能分别放在单独的类中,并让这个类包含它要装饰的对象,当需要执行时,客户端就可以有选择地、按顺序地使用装饰功能包装对象。

    但是在C++中语法层级不支持无感知装饰。

    Demo

    #include 
    using namespace std;
    
    class Car
    {
    public:
    	virtual void show() = 0;
    protected:
    private:
    };
    
    class RunCar : public Car
    {
    public:
    	void run()
    	{
    		cout << "可以跑" << endl;
    	}
    	virtual void show()
    	{
    		run();
    	}
    protected:
    private:
    };
    
    class SwimCarDirector : public Car
    {
    public:
    	SwimCarDirector(Car *p)
    	{
    		m_p = p;
    	}
    
    	void swim()
    	{
    		cout << "可以游" << endl;
    	}
    
    	virtual void show()
    	{
    		m_p->show();
    		swim();
    	}
    private:
    	Car *m_p;
    };
    
    class FlyCarDirector : public Car
    {
    public:
    	FlyCarDirector(Car *p)
    	{
    		m_p = p;
    	}
    
    	void fly()
    	{
    		cout << "可以飞" << endl;
    	}
    	virtual void show()
    	{
    		m_p->show();
    		fly();
    	}
    private:
    	Car *m_p;
    };
    
    void main()
    {
    	Car *runcar = NULL;
    	runcar = new RunCar;
    	runcar->show();
    
    	cout <<"车开始装饰swim"<show();
    
    	cout <<"车开始装饰fly"<show();
    
    	delete flyCar;
    	delete swimCar;
    	delete runcar;
    	
    	return ;
    }

    适配器模式

    Abstract

    Adapter模式也叫适配器模式,是构造型模式之一,通过Adapter模式可以改变已有类(或外部类)的接口形式。

    适用于:

    是将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

    Demo

    #include 
    using namespace std;
    
    class Current18v
    {
        public:
        void use18vCurrent()
        {
            cout << "使用18v的交流电" << endl;
        }
        protected:
        private:
    };
    
    
    class Current220v
    {
        public:
        void use220vCurrent()
        {
            cout << "使用220v的交流电" << endl;
        }
        protected:
        private:
    };
    
    
    class Adapter : public Current18v
    {
    public:
    Adapter(Current220v *p220v)
    {
    m_p220v = p220v;
    }
    void use18vCurrent()
    {
    cout << "adapter中使用电流" << endl;
    m_p220v->use220vCurrent();
    }
    protected:
    private:
    Current220v *m_p220v;
    };
    
    void main()
    {
        Current220v *p220v = new Current220v;
        Adapter *padapter = new Adapter(p220v);
        padapter->use18vCurrent();
        
        delete p220v;
        delete padapter;
        system("pause");
        return ;
    }

    组合模式

    Abstract

    Composite模式也叫组合模式,是构造型的设计模式之一。通过递归手段来构造树形的对象结构,并可以通过一个对象来访问整个对象树。

    Role

    Component (树形结构的节点抽象)

    - 为所有的对象定义统一的接口(公共属性,行为等的定义)

    - 提供管理子节点对象的接口方法

    - [可选]提供管理父节点对象的接口方法

    Leaf (树形结构的叶节点)

    Component的实现子类

    Composite(树形结构的枝节点)

    Component的实现子类

    适用于:

    单个对象和组合对象的使用具有一致性。将对象组合成树形结构以表示“部分--整体”

    Demo

    #include 
    using namespace std;
    #include "list"
    #include "string"
    
    //
    class IFile
    {
    public:
    	virtual void display() = 0;
    	virtual int add(IFile *ifile) = 0;
    	virtual int remove(IFile *ifile) = 0;
    	virtual list* getChild() = 0;
    protected:
    private:
    };
    
    class File : public IFile
    {
    public:
    	File(string name)
    	{
    		m_list = NULL;
    		m_name = "";
    		m_name = name;
    	}
    	~File()
    	{
    		if (m_list != NULL)
    		{
    			delete m_list;
    		}
    	}
    	virtual void display()
    	{
    		cout << m_name << endl;
    	}
    	virtual int add(IFile *ifile)
    	{
    		return -1;
    	}
    	virtual int remove(IFile *ifile)
    	{
    		return -1;
    	}
    	virtual list* getChild() 
    	{
    		return NULL;
    	}
    
    private:
    	list *	m_list;
    	string		m_name;
    
    };
    
    class Folder : public IFile
    {
    public:
    	Folder(string name)
    	{
    		m_name = name;
    		m_list = new list;
    	}
    	~Folder()
    	{
    		if (m_list == NULL)
    		{
    			delete m_list;
    		}
    	}
    	virtual void display()
    	{
    		cout << m_name << endl;
    	}
    	virtual int add(IFile *ifile)
    	{
    		m_list->push_back(ifile);
    		return 0;
    	}
    	virtual int remove(IFile *ifile)
    	{
    		m_list->remove(ifile);
    		return 0;
    	}
    	virtual list* getChild() 
    	{
    		return m_list;
    	}
    
    private:
    	list *	m_list;
    	string			m_name;
    
    };
    
    void showTree(IFile *ifile, int level)
    {
    	list *l = NULL;
    	int i = 0;
    	for (i=0; idisplay();
    
    	l = ifile->getChild();
    	if (l != NULL)
    	{
    		for (list::iterator it=l->begin(); it!=l->end(); it++)
    		{
    			if ( (*it)->getChild() == NULL)
    			{
    				for (i=0; i<=level; i++) //注意 <= 
    				{
    					printf("\t");
    				}
    				(*it)->display();
    			}
    			else
    			{
    				showTree((*it), level + 1);
    			}
    
    		}
    	}
    }
    
    void main()
    {
    	Folder *root = new Folder("C:");
    
    	Folder *dir1 = new Folder("111dir");
    	File *txt1 = new File("aaa.txt");
    
    	Folder *dir12 = new Folder("222dir");
    	//dir12->display();
    	File *txt12 = new File("222.txt");
    	//txt12->display();
    
    	
    	root->display();
    	root->add(dir1);
    	root->add(txt1);
    
    	dir1->add(dir12);
    	dir1->add(txt12);
    
    	/*
    	list *l = dir1->getChild();
    	for (list::iterator it=l->begin(); it!=l->end(); it++)
    	{
    		(*it)->display();
    	}
    	*/
    	//开发一个递归函数 现在根结点下的所有子结点
    	cout << "测试递归函数" << endl;
    
    	showTree(root, 0);
    
    	delete txt12;
    	delete dir12;
    	delete dir1;
    	delete txt1;
    	delete root;
    	cout<<"hello..."<

    桥接模式 bridge

    Abstract

    Bridge 模式又叫做桥接模式,是构造型的设计模式之一。Bridge模式基于类的最小设计原则,通过使用封装,聚合以及继承等行为来让不同的类承担不同的责任。它的主要特点是把抽象(abstraction)与行为实现(implementation)分离开来,从而可以保持各部分的独立性以及应对它们的功能扩展。

    Role

    Client

    Bridge模式的使用者

    Abstraction

    抽象类接口(接口或抽象类)维护对行为实现(Implementor)的引用

    Refined Abstraction

    Abstraction子类

    Implementor

    行为实现类接口(Abstraction接口定义了基于Implementor接口的更高层次的操作)

    ConcreteImplementor

    Implementor子类

    Demo

    class Engine
    {
    public:
    	virtual void installEngine() = 0;
    };
    
    class Engine4000 : public Engine
    {
    public:
    	virtual void installEngine()
    	{
    		cout << "安装发动机 Engine4000" << endl;
    	}
    };
    
    class Engine3500 : public Engine
    {
    public:
    	virtual void installEngine()
    	{
    		cout << "安装发动机 Engine 3500" << endl;
    	}
    };
    
    class Car
    {
    public:
    	Car(Engine *pengine)
    	{
    		m_engine = pengine;
    	}
    	virtual void installEngine() = 0;
    
    protected:
    	Engine *m_engine;
    };
    
    class BMW7 :public Car
    {
    public:
    	BMW7(Engine *p) : Car(p)
    	{
    
    	}
    
    	//注意车的安装  和 发动机的安装 不同之处
    	virtual void installEngine()
    	{
    		cout << "BMW7 " ; 
    		m_engine->installEngine();
    	}
    protected:
    private:
    };
    
    void main163()
    {
    	Engine4000 *e4000 = new Engine4000;
    	BMW7 *bmw7 = new BMW7(e4000);
    	bmw7->installEngine();
    
    	delete bmw7;
    	delete e4000;
    }
    void main()
    {
    	//main1601();
    	//main1602();
    	main163();
    	system("pause");
    }

    外观模式 facade

    Abstract

    Facade模式为一组具有类似功能的类群,比如类库,子系统等等,提供一个一致的简单的界面。这个一致的简单的界面被称作facade。

    Role

    Façade

    为调用方, 定义简单的调用接口。

    Clients

    调用者。通过Facade接口调用提供某功能的内部类群。

    Packages

    功能提供者。指提供功能的类群(模块或子系统)

    Demo

    #include 
    using namespace std;
    
    class SystemA
    {
    public:
    	void doThing()
    	{
    		cout << "systemA do...." << endl;
    	}
    };
    
    class SystemB
    {
    public:
    	void doThing()
    	{
    		cout << "systemA do...." << endl;
    	}
    };
    
    class SystemC
    {
    public:
    	void doThing()
    	{
    		cout << "systemA do...." << endl;
    	}
    };
    
    class Facade
    {
    public:
    	Facade()
    	{
    		a = new SystemA;
    		b = new SystemB;
    		c = new SystemC;
    	}
    	~Facade()
    	{
    		delete a;
    		delete b;
    		delete c;
    	}
    
    	void doThing()
    	{
    		a->doThing();
    		b->doThing();
    		c->doThing();
    	}
    
    protected:
    private:
    	SystemA *a;
    	SystemB *b;
    	SystemC *c;
    };
    
    
    void main1414()
    {
    	/*
    	SystemA *a = new SystemA;
    	SystemB *b = new SystemB;
    	SystemC *c = new SystemC;
    
    	a->doThing();
    	b->doThing();
    	c->doThing();
    
    	delete a;
    	delete b;
    	delete c;
    	*/
    
    	Facade *f = new Facade;
    	f->doThing();
    	delete f;
    	cout<<"hello..."<

    享元模式flyweight

    Abstract

    FlyWeight 模式也叫做享元模式,通过与其他的类似对象共享数据来减少内存的使用。

    Role

    抽象享元角色:

    所有具体享元类的父类,规定一些需要实现的公共接口。

    具体享元角色:

    抽象享元角色的具体实现类,并实现了抽象享元角色规定的方法。

    享元工厂角色:

    负责创建和管理享元角色。

    使用场景:

    是以共享的方式,高效的支持大量的细粒度的对象。

    Demo

    #include 
    using namespace std;
    #include "string"
    #include "map"
    
    class Person
    {
    public:
    	Person(string name, int age, int sex)
    	{
    		this->name = name;
    		this->age = age;
    		this->sex = sex;
    	}
    	string getName()
    	{
    		return name;
    	}
    	int getAge()
    	{
    		return age;
    	}
    	int getSex()
    	{
    		return sex;
    	}
    protected:
    	string	name;
    	int		age;
    	int		sex; //1男 2女
    };
    
    class Teacher : public Person
    {
    public:
    	Teacher(string id, string name, int age, int sex) : Person(name, age, sex)
    	{
    		this->id = id;
    	}
    
    	string getId()
    	{
    		return id;
    	}
    	void printT()
    	{
    		cout << "id:" <::iterator it = m_tpool.begin();
    			tmp = it->second;
    			m_tpool.erase(it);
    			delete tmp;
    		}
    	}
    	//通过Teacher的pool,来存放老师结点,在TeacherFactory中创建老师、销毁老师
    	Teacher *getTeacher(string tid)
    	{
    		string	name;
    		int		age;
    		int		sex;
    		
    		Teacher *tmp = NULL;
    		map::iterator it =  m_tpool.find(tid);
    		if (it == m_tpool.end())
    		{
    			cout << "id为: " << tid << " 的老师不存在,系统为你创建该老师,请输入以下信息" <> name;
    			cout << "请输入老师年龄:";
    			cin >> age;
    			cout << "请输入老师性别 1男 2女:";
    			cin >> sex;
    			tmp = new Teacher(tid, name, age, sex);
    			m_tpool.insert(pair(tid, tmp));
    		}
    		else
    		{
    			tmp = (it->second);
    		}
    		return tmp;
    	}
    
    private:
    	map m_tpool;
    };
    
    
    void main()
    {
    	/*
    	Teacher *t1 = new Teacher("001", "小李", 30, 1);
    	Teacher *t2 = new Teacher("002", "小张", 30, 1);
    	Teacher *t3 = new Teacher("001", "小李", 30, 1);
    	Teacher *t4 = new Teacher("004", "小吴", 30, 1);
    	//
    	cout << "t1 t3的 工号一样,但是也不是同一个人 " << endl;
    	delete t1;
    	delete t2;
    	delete t3;
    	delete t4;
    	*/
    	TeacherFactory *teacherFactory = new TeacherFactory;
    	Teacher *t1 = teacherFactory->getTeacher("001");
    	t1->printT();
    
    	Teacher *t2 = teacherFactory->getTeacher("001");
    	t2->printT();
        delete teacherFactory;
    	system("pause");
    	return ;
    }

  • 相关阅读:
    Tomcat 服务详解
    针对海洋数据的管理三维gis软件系统有何优势
    LeetCode 0216.组合总和 III:回溯(剪枝) OR 二进制枚举
    Flume学习笔记
    Spring Cloud Alibaba 分布式微服务高并发数据平台化(中台)思想+多租户saas设计的企业开发架构
    响应式动画登录
    李宏毅2023机器学习作业HW05解析和代码分享
    mkv转mp4,大家都在用的方法
    解决Intellij IDEA @Test没有提示问题
    NNDL 作业8:RNN - 简单循环网络
  • 原文地址:https://blog.csdn.net/qq_32378713/article/details/126171872