第六章 穿什么有这么重要-装饰模式(读书笔记)

本文通过小菜扮靓的三个版本逐步展示了装饰模式的设计思想。装饰模式可以在不修改原始类的基础上为其添加新功能,提高了代码的灵活性和复用性。文章通过具体的代码示例解释了装饰模式的基本原理及其实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第六章 穿什么有这么重要-装饰模式

1.装饰模式(Decorator):动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活。
2.(图6.4)Component是定义一个对象接口,可以给这些对象动态地添加职责。ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。Decorator:装饰抽象类,继承了Component从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的.至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。
3.装饰模式是利用SetComponent来对对象进行包装的。这样每个装饰对象的实现就和如何使用这个对象分离开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中。
4.装饰模式是为己有功能动态地添加更多功能的一种方式。当系统需要新功能的时候,是向旧的类中添加新的代码。这些新加的代码通常装饰了原有类的核心职责或主要行为。
5.装饰模式可以让你全副武装到牙齿,也可以让你只挂一丝到内裤。
6.装饰模式的优点是:把类中的装饰功能从类中搬移去除,这样可以简化原有的类。最大的好处是有效地把类的核心职责和装饰功能区分开了。而且可以去除相关类中重复的装饰逻辑。
7.保证装饰类之间彼此独立,这样他们就可以以任意的顺序进行组合了。

 

图6.4 装饰模式的UML图

----------------------------------------------------------------------------------------------------------------------

6.2 小菜扮靓第一版

6.2程序 小菜扮靓第一版程序实现。如果要增加超人的装扮的话,就会违反开放封闭原则。

6.2.1 Person.h

#pragma once
#include <string>
#include <iostream>

class Person
{
public:
	Person(std::string name)
	{
		m_Name = name;
	};

	void WearTShirts(void)
	{
		std::cout << "大T恤" << std::endl;
	};

	void WearBigTrouser(void)
	{
		std::cout << "垮裤" << std::endl;
	};

	void WearSneakers(void)
	{
		std::cout << "破球鞋" << std::endl;
	};

	void WearSuit(void)
	{
		std::cout << "西装" << std::endl;
	};

	void WearTie(void)
	{
		std::cout << "领带" << std::endl;
	};

	void WearLeatherShoes(void)
	{
		std::cout << "皮鞋" << std::endl;
	};

	void Show(void)
	{
		std::cout << "装扮的" 
			<< m_Name << std::endl;
	};
private:
	std::string m_Name;
};

 

6.2.2 客户端程序

#include "stdafx.h"
#include "Person.h"

int _tmain(int argc, _TCHAR* argv[])
{
	Person* person = new Person("小菜");

	std::cout << "第一种装扮" << std::endl;
	person->WearBigTrouser();
	person->WearTShirts();
	person->WearSneakers();
	person->Show();

	std::cout << "第2种装扮" << std::endl;
	person->WearSuit();
	person->WearLeatherShoes();
	person->WearTie();
	person->Show();
	return 0; 
}

----------------------------------------------------------------------------------------------------------------------

6.3 小菜扮靓第二版(图6.3) 用了继承和抽象类。

 6.3 小菜扮靓第二版的代码实现

6.3.1 Person.h

#pragma once
#include <string>
#include <iostream>

class Person
{
public:
	Person(std::string name)
	{
		m_Name = name;
	};

	void Show(void)
	{
		std::cout << "装扮的" 
			<< m_Name << std::endl;
	};
private:
	std::string m_Name;
};

//服饰抽象类
class Finery
{
public:
	virtual void Show(void) = 0;
};


class TShirts :public Finery
{
public:
	void Show(void)
	{
		std::cout << "大T恤" << std::endl;
	};
};

class BigTrouser :public Finery
{
public:
	void Show(void)
	{
		std::cout << "垮裤" << std::endl;
	};
};

class Sneakers :public Finery
{
public:
	void Show(void)
	{
		std::cout << "破球鞋" << std::endl;
	};
};

class Suit :public Finery
{
public:
	void Show(void)
	{
		std::cout << "西装" << std::endl;
	};
};


class Tie :public Finery
{
public:
	void Show(void)
	{
		std::cout << "领带" << std::endl;
	};
};

class LeatherShoe :public Finery
{
public:
	void Show(void)
	{
		std::cout << "皮鞋" << std::endl;
	};
};

 

6.3.2 客户端代码

#include "stdafx.h"
#include "person.h"

int _tmain(int argc, _TCHAR* argv[])
{
	Person* xiaocai = new Person("小菜");
	Finery* dtx = new TShirts(); 
	Finery* kk = new BigTrouser();
	Finery* pqx = new Sneakers();

	dtx->Show();
	kk->Show();
	pqx->Show();
	xiaocai->Show();
	return 0;
}

这样写就好比你光着身子,当着大家的面,先穿T恤,再穿裤子,再穿鞋,仿佛在跳脱衣舞。这里有点建造者模式的味道,但是建造者模式的建造过程是稳定的,这里却不稳定。

----------------------------------------------------------------------------------------------------------------------

6.5 小菜扮靓第三版(图6.5)


6.5.1 Person.h

#pragma once
#include <string>
#include <iostream>

class Person
{
public:
	Person(std::string name)
	{
		m_name = name;
	};
	virtual void Show(void)
	{
		std::cout << "装扮的" << m_name << std::endl;
	};
	Person(){};
private:
	std::string m_name;
};

//服饰类
class Finery :public Person
{
public:
	void Decorator(Person* comp)
	{
		this->m_pComponent = comp;
	};

	void Show(void)
	{
		if (m_pComponent != NULL)
		{
			m_pComponent->Show();
		}
	};
protected:
	Person* m_pComponent;
};

//具体服饰类
class TShirts :public Finery
{
public:
	void Show(void)
	{
		std::cout << "大T恤" << std::endl;
		Finery::Show();
	}
};

class BigTrouser :public Finery
{
public:
	void Show(void)
	{
		std::cout << "垮裤" << std::endl;
		Finery::Show();
	};
};

class Sneakers :public Finery
{
public:
	void Show(void)
	{
		std::cout << "破球鞋" << std::endl;
		Finery::Show();
	};
};

class Suit :public Finery
{
public:
	void Show(void)
	{
		std::cout << "西装" << std::endl;
		Finery::Show();
	};
};


class Tie :public Finery
{
public:
	void Show(void)
	{
		std::cout << "领带" << std::endl;
		Finery::Show();
	};
};

class LeatherShoe :public Finery
{
public:
	void Show(void)
	{
		std::cout << "皮鞋" << std::endl;
		Finery::Show();
	};
};


6.5.2 客户端代码

#include "stdafx.h"
#include "Person.h"

int _tmain(int argc, _TCHAR* argv[])
{
	Person* xiaocai = new Person("小菜");
	std::cout << "第一个装扮" << std::endl;
	
	Sneakers* pqx = new Sneakers();
	BigTrouser* kk = new BigTrouser();
	TShirts* dtx = new TShirts();

	pqx->Decorator(xiaocai);
	kk->Decorator(pqx);
	dtx->Decorator(kk);
	dtx->Show();

	std::cout << "第二个装扮" << std::endl;
	LeatherShoe* px = new LeatherShoe();
	Tie* tie = new Tie();
	Suit* suit = new Suit();
	px->Decorator(xiaocai);
	tie->Decorator(px);
	suit->Decorator(tie);
	suit->Show();
	return 0;
}

 光着膀子,打着领带,下身跨裤,左脚皮鞋,右脚破球鞋的极具个性的形象就可以简简单单的实现了。这个例子就是装饰者模式的完美体现。

----------------------------------------------------------------------------------------------------------------------



 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的横打

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值