当前位置: 首页 > news >正文

旅游营销网站开发湖南长沙最新情况

旅游营销网站开发,湖南长沙最新情况,建程网官网平台,免费网站模板带后台下载面向对象设计原则 接口隔离原则:面向对象设计之接口隔离原则-CSDN博客 设计模式 工厂模式 : 设计模式之工厂模式-CSDN博客 迭代器模式:设计模式之迭代器模式-CSDN博客 适配器模式:设计模式之适配器模式-CSDN博客 过滤器模式&#…

面向对象设计原则

接口隔离原则:面向对象设计之接口隔离原则-CSDN博客

设计模式

工厂模式 : 设计模式之工厂模式-CSDN博客

迭代器模式:设计模式之迭代器模式-CSDN博客

适配器模式:设计模式之适配器模式-CSDN博客

过滤器模式:设计模式之过滤器模式-CSDN博客

单例模式:设计模式之单例模式-CSDN博客

观察者模式:设计模式之观察者模式-CSDN博客

空对象模式:设计模式之空对象模式-CSDN博客

目录

1.概述

2.结构

3.实现

3.1.示例1:简单实现

3.2.示例2:函数装饰器

4.总结


1.概述

        装饰器模式也是我们日常编程用的比较多的一种设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构,实际上就是现有的类的一个包装。这种模式可以视为结构性模式,应为它提供了一种用于组合类的机制,,使得这些类可以在不改变其代码的情况下进行扩展。

        在装饰器模式中,有一个被装饰的组件(通常是抽象类或接口),它定义了需要实现的方法。然后,有一个装饰器类,它实现了同样的接口,并且包装了被装饰的组件。装饰器类可以在被装饰的组件方式调用之前或之后添加额外的功能。

2.结构

装饰器模式的UML类图如下:

主要角色:

1)抽象组件(Component):定义了原始对象和装饰器对象的公共接口或抽象类,可以是具体组件类的父类或接口。

2)具体组件(Concrete Component):是被装饰的原始对象,它定义了需要添加新功能的对象。

3)抽象装饰器(Decorator):这是一个抽象基类或接口,它也实现了组件接口,并包含一个成员变量用来引用具体组件对象。装饰器可以添加额外的功能,通常通过在装饰器中委托给具体组件实现。

4)具体装饰器(Concrete Decorator):实现了抽象装饰器的接口,负责向抽象组件添加新的功能。具体装饰器通常会在调用原始对象的方法之前或之后执行自己的操作。

        装饰器模式通过嵌套包装多个装饰器对象,可以实现多层次的功能增强。每个具体装饰器类都可以选择性地增加新的功能,同时保持对象接口的一致性。

        在C++中,装饰器模式通常涉及到类的继承和组合,以及对虚函数的使用,以确保适当的方法可以在组合中被调用。这使得C++的装饰器模式非常灵活,可用于构建可维护和可扩展的对象结构。

3.实现

3.1.示例1:简单实现

Decorator.h

#include <iostream>
#include <memory>// 抽象组件
class Component {
public:virtual void doWork() = 0;
};// 具体组件
class ConcreteComponent : public Component {
public:void doWork() override {// 执行具体操作std::cout << "ConcreteComponent doWork..." << std::endl;}
};// 抽象装饰器
class Decorator : public Component {
protected:Component* m_pComponent;
public:Decorator(Component* pComponent) : m_pComponent(pComponent) {}void doWork() override {m_pComponent->doWork();}
};// 具体装饰器
class ConcreteDecorator1 : public Decorator {
public:ConcreteDecorator1(Component* pComponent) : Decorator(pComponent) {}void doWork() override {std::cout << "ConcreteDecorator1 doWork before..." << std::endl;__super::doWork();std::cout << "ConcreteDecorator1 doWork after..." << std::endl;}
};// 具体装饰器
class ConcreteDecorator2 : public Decorator {
public:ConcreteDecorator2(Component* pComponent) : Decorator(pComponent) {}void doWork() override {std::cout << "ConcreteDecorator2 doWork before..." << std::endl;__super::doWork();std::cout << "ConcreteDecorator2 doWork after..." << std::endl;}
};

main.cpp

int main()
{std::unique_ptr<Component> pConcreteComponent(new ConcreteComponent());std::unique_ptr<Component> pConcreteDecorator1(new                     ConcreteDecorator1(pConcreteComponent.get()));std::unique_ptr<Component> pConcreteDecorator2(new ConcreteDecorator2(pConcreteDecorator1.get()));pConcreteComponent->doWork();std::cout << std::endl;pConcreteDecorator1->doWork();std::cout << std::endl;pConcreteDecorator2->doWork();
}

输出:

ConcreteComponent doWork...ConcreteDecorator1 doWork before...
ConcreteComponent doWork...
ConcreteDecorator1 doWork after...ConcreteDecorator2 doWork before...
ConcreteDecorator1 doWork before...
ConcreteComponent doWork...
ConcreteDecorator1 doWork after...
ConcreteDecorator2 doWork after...

pConcreteComponent和pConcreteDecorator1还比较简单,pConcreteDecorator2装饰器就比较复杂了,就好像是在pConcreteDecorator1的基础上套了一个壳,从这点也可以看出装饰器模式结构可以非常的灵活。

3.2.示例2:函数装饰器

        虽然装饰器模式通常用于类,但是同样可以应用于函数。例如,假设代码中有一个特定的函数给你带来了麻烦:你希望记录该函数被调用的所有时间,并在Excel中分析统计信息。当然,这可以通过在调用函数前后放置一些代码来实现,即

cout<< "Entering function XYz\n":
// do the work
cout <<"Exiting function XYZ\n";

        这很好,但从关注点分离的角度来看并不好:我们确实希望将日志功能存储在某个地方,以便复用并在必要时强化它。
        有不同的方法可以实现这一点。一种方法是简单地将整个工作单元作为一个函数提供给某些日志组件:

struct Logger{function<void()> func;string name;
public:Logger(const function<void()>& func, const string& name):func{func},name{name}{}void operator()()const {cout<< "Entering "<< name << "\n";func();cout<< "Exiting "<< name << "\n";}
};

使用这种方法,我们可以编写如下代码来使用它:

Logger([](){ cout << "Hello\n";},“HelloFunction")();// Entering HelloFunction
// Hello
// Exiting HelloFunction

始终有一种选择,可以将函数作为模板参数而不是std::function传人。这导致与前面的结果略有不同:

template <typename Func>
struct Logger2{Func func;string name;
public:Logger2(const Func& func,const string& name):func{func},name{name}{}void operator()()const{cout << "Entering "<< name << endl;func();cout << "Exiting "<< name << endl;}
};

此实现的用途完全不变。我们可以创建一个工具函数来实际创建这样的记录器:

template <typename Func> 
auto make_logger2(Func func,const string& name)
{return logger2<Func>{ func, name };
}

然后像下面这样使用它:

auto call = make_logger2([](){cout <<"Hello!" <<endl; },"HelloFunction");
call();// output same as before

你可能会问 "这有什么意义?" 嗯……我们现在有能力在需要装饰某个函数时创建一个装饰器(其中包含装饰的函数)并调用它。
现在,我们遇到了一个新的挑战:如果要记录调用函数add()的日志,该怎么办呢?此处将add()函数定义如下:

double add(double a, double b)
{cout << a << "+"<< b<<"="<<(a + b)<< endl;return a + b;
}

需要 add()函数的返回值吗?如果需要的话,它将从 1ogger中返回(因为1ogger装饰了add()函数)。这并不容易!但也绝不是不可能。我们再次改进一下记录器:

template <typename R, typename... Args>
struct Logger3<R(Args...)>
{Logger3(function<R(Args...)>func, const string& name): func{func},name{name}{}R operator()(Args ...args){    cout << "Entering"<< name << endl;R result = func(args...);cout <<"Exiting "<< name << endl;return result;}function<R(Args ...)> func;string name;
};

在上述代码中,模板参数R表示返回值的类型,Args表示丽数的参数类型。与之前相同的是,装饰器在必要时调用函数;唯一的区别是opeIator() 返回了一个R,因此采用方法不会丢失返回值。
        我们可以构造另一个工具函数 make_:

template <typename R, typename... Args>
auto make_1ogger3(R(*func)(Args...), const string& name)
{return Logger3<R(Args...)>(function<R(Args...)>(func)name);
}

请注意,这里没有使用std::function,而是将第一个参数定义为普通函数指针,我们现在可以使用此函数实例化日志调用并使用它:

auto logged add = make logger3(add, "Add");
auto result=logged add(2,3);

当然,make_logger3可以被依赖注入取代。这种方法的好处是能够:
1)通过提供空对象而不是实际的记录器,动态地打开和关闭日志记录 。
2)禁用记录器正在记录的代码的实际调用(同样,通过替换其他记录器)。
总之,对于开发人员而言,这是一个有用的工具函数。

4.总结

使用装饰器模式的好处:

1)可以在运行时动态的添加或删除功能。

2)可以递归地组合多个装饰器,从而创建复杂的对象。

3)可以使用不同的装饰器组合来创建不同的行为。

4)可以在不修改原有代码的情况下增加新功能。

总体来说,装饰器模式是一种强大且灵活的设计模式,它可以用于创建可扩展、可定制和可组合的对象。

http://www.dt0577.cn/news/44143.html

相关文章:

  • 做商城网站需要备案什么域名百度官方客服
  • 做摄影和后期的兼职网站网络推广策划
  • 赣州58同城网长沙百度网站优化
  • 推广网上国网有什么好处网站seo外链平台
  • 海外短视频怎么下载辽宁好的百度seo公司
  • 企业开办网站拓客公司联系方式
  • 做网站绘制蓝图的步骤网络热词2022
  • 揭阳住房和城乡建设厅网站百度快速排名软件
  • 学生个人网页内容排版设计作品代做seo关键词排名
  • 做网站毕业设计存在的问题win7优化大师官方网站
  • 个人网站建设实训目的网络推广竞价是什么
  • 备案成功的网站可以更换域名吗超链接友情外链查询
  • 橱柜企业网站模板百度推广平台
  • 如何鉴定网站做的好坏长沙百度快照优化排名
  • 如何做网站的推广教程国内新闻最新消息简短
  • wordpress08影视站推广普通话心得体会
  • 内部劵淘网站怎么做百度开户公司
  • 视频教学互动网站建设西安网络推广公司网络推广
  • 如何用ps做网站标识惠州短视频seo
  • 做网站原型图软件市场推广方案ppt
  • 海口模板建站哪家好网站设计费用明细
  • 查询自己网站外链网络营销的策划流程
  • 微信服务号菜单链接网站怎么做设计网页
  • 迎访问中国建设银行网站-360指数官网
  • 做电影视频网站赚钱嘛宁波seo网络推广定制
  • 做推广要知道的网站广告投放公司
  • 独立站seo推广推手平台哪个靠谱
  • it外包公司上海东莞seo项目优化方法
  • 厦门购买域名以后搭建网站百度一下你就知道移动首页
  • 中能建西北城市建设门户网站外链信息