首页 > 其他分享 >策略模式(strategy)

策略模式(strategy)

时间:2023-09-07 18:23:45浏览次数:27  
标签:__ 策略 discountStrategy MovieTicket 模式 strategy discount originalPrice

策略模式(Strategy)

1、作用

策略模式的主要目的主要是将算法的定义(strategy类)和使用分开(context类),也就是将算法的行为和环境分开,将算法的定义放在专门的策略类中,每一个策略类封装一个实现算法。而使用算法的环境中针对抽象策略编程,而不是针对实现编程,符合依赖倒置原则。

2、实现方式

策略模式包含以下3个角色:

  (1)Context(环境类):负责使用算法策略,其中维持了一个抽象策略类的引用实例。

  (2)Strategy(抽象策略类):所有策略类的父类,为所支持的策略算法声明了抽象方法。=> 既可以是抽象类也可以是接口

  (3)ConcreteStrategy(具体策略类):实现了在抽象策略类中声明的方法。

比如要开发一个电影售票系统,将这个系统封装为MovieTicket类,售票系统要使用一些打折的策略,如果把这些打折的策略实现在MovieTicket类中,那么如果增加或者修改打折策略就需要修改MovieTicket类。使用策略模式,那么就把MovieTicket当做使用算法的类(Context类),而将策略抽象成一个DiscountStrategy类,MovieTicket类依赖于DiscountStrategy类进行编程,这样继承于DiscountStragegy类的具体策略类有修改或者新增不需要修改MovieTicket类。

优点:

  这里主要的好处是对MovieTicket中使用的策略满足的开闭原则

缺点:

  对于使用MovieTicket这个类的用户就不友好了,他需要具体有哪些策略,将策略的选择留给了用户,增加了用户代码的复杂度(扩展性、使用灵活性就要付出代付复杂的代价。)

这个例子对应的UML图:

img

3、C++代码

Discount.h

#include <iostream>
#include <memory>   // shared_ptr

#ifndef __DISCOUNT__H__
#define __DISCOUNT__H__

using namespace std;


class DiscountStrategy {                                         // 策略的抽象基类,定义接口。有的像模板模式的模板,但模板模式定义死了一个模板函数。
    public:
        virtual float getPrice(float originalPrice) = 0;
};

class ChildrenDiscount : public DiscountStrategy {               // 扩展的一种打折策略,小孩打折————免费。
    public:
        float getPrice(float originalPrice) override {
            return 0;
        }

        ~ChildrenDiscount() { cout<<"distroy ChildrenDiscount..."<<endl; }
};

class StudentDiscount : public DiscountStrategy {               // 扩展的一种打折策略,学生打折————半价。
    public:
        float getPrice(float originalPrice) override {
            return originalPrice * 0.5;
        }

        ~StudentDiscount() { cout<<"distroy StudentDiscount...."<<endl; }
};

class VIPDiscount : public DiscountStrategy {                   // 扩展的一种打折策略,会员打折————8折。
    public:
        float getPrice(float originalPrice) override {
            return originalPrice * 0.8;
        }

        ~VIPDiscount() { cout<<"distroy VIPDiscount...."<<endl; }
};




class MovieTicket {
    public:
        MovieTicket(shared_ptr<DiscountStrategy> discount) : discountStrategy(discount) {}

        void setDiscountStrategy(shared_ptr<DiscountStrategy> discount) {
            discountStrategy = discount;
        }
        float discount(float originalPrice) {
            return discountStrategy->getPrice(originalPrice);
        }
    private:
        shared_ptr<DiscountStrategy> discountStrategy;
};


#endif

test.cc

#include <iostream>
#include <memory>
#include "Discount.h"

int main() {
    shared_ptr<DiscountStrategy> discountStrategy = make_shared<StudentDiscount>();
    MovieTicket movieTicket(discountStrategy);                                                      // 在对电影票使用学生票的打折策略
    double originalPrice = 100;
    double discountPrice = movieTicket.discount(originalPrice);
    cout<<"StudentDiscount: originalPrice="<<originalPrice<<", discountPrice="<<discountPrice<<endl;

    movieTicket.setDiscountStrategy(make_shared<ChildrenDiscount>());                               // 在对电影票使用儿童票的打折策略
    discountPrice = movieTicket.discount(originalPrice);
    cout<<"ChildrenDiscount: originalPrice="<<originalPrice<<", discountPrice="<<discountPrice<<endl;

    movieTicket.setDiscountStrategy(make_shared<VIPDiscount>());                                    // 在对电影票使用会员票的打折策略
    discountPrice = movieTicket.discount(originalPrice);
    cout<<"VIPDiscount: originalPrice="<<originalPrice<<", discountPrice="<<discountPrice<<endl;

    return 0;
}

输出:

img

在这个例子中,MovieTicket类要保存一个DiscountStrategy的一个指针,为了好管理指针,这里使用了智能指针,省去了指针的复杂管理。

标签:__,策略,discountStrategy,MovieTicket,模式,strategy,discount,originalPrice
From: https://www.cnblogs.com/yuandonghua/p/17685765.html

相关文章

  • 模板模式(template)
    模板模式(Template)1、作用做一件是的方法很多,但做这件都可以归纳为几个步骤。这个时候可以使用模板模式,在模板类中,定义做事的步骤,将多种实现做事的细节延迟到子类中去实现。即:定义一个操作中的算法的骨架(模板函数),而将一些步骤延迟到子类中(基本函数)。模板方法使得子类可以不改变......
  • 外观模式(facade)
    外观模式(Facade)1、作用(1)、将各个子系统的接口汇聚在一起,定义一个统一的接口方便客户使用,满足“迪米特法则”,即客户不需要了解子系统,只需要知道Facade模式封装的类即可以使用所有子系统。(2)、隔离用户和子系统,将用户与子系统解耦,当子系统有修改是,顶多修改Facade模式封装的类,无需......
  • 桥接模式
    桥接模式1作用当类的模型有两个或多个维度的时候,如果两个变化维度用同一个类使用继承方式实现会变得很复杂(冗余代码很多),不易于维护和扩展(继承关系是一种强耦合关系),为了降低耦合关系,提高维护性和可扩展性,可以将两个变化维度的通过两个类(abstruction、implementor类)来实现,将两......
  • LRUCache算法缓存策略(map+doubleLinkedList)
    packagearithmetic;importjava.util.HashMap;publicclassFaceTest81{//LRUcache缓存策略map+双向链表//get、update、put需要时间复杂度达到O1//map+双向链表结构publicFaceTest81(intcapacity){ cache=newMyCache(capacity);}privateMyCache<Integer,Intege......
  • 韬客时代卷轴模式系统开发介绍和部分核心源码
    韬客时代是一种卷轴模式系统。什么是卷轴模式呢?新用户注册,先送你一部分积分,该积分用于兑换一个初始任务,俗称卷轴!卷轴模式的赚钱的原理是,你用积分兑换初级任务包,完成卷轴任务之后,你可以获得更多的积分,然后复投,达到一定数量后可以兑换更高级的任务包,任务包越高级每次获得的积分也就越......
  • kafka复习:(24)consume-transform-produce模式
    packagecom.cisdi.dsp.modules.metaAnalysis.rest.kafka2023;importorg.apache.kafka.clients.consumer.*;importorg.apache.kafka.clients.producer.KafkaProducer;importorg.apache.kafka.clients.producer.ProducerConfig;importorg.apache.kafka.clients.produc......
  • 区域LIS应用平台 云技术的SaaS模式
    在医疗机构内部,院内实验室主要负责本院临床科室的检验,院内LIS系统必须满足实验室日常的标本处理入库、仪器联机、检验结果处理、报告打印、报告发布、检验信息统计、检验信息报告发布、标本流程、外部医疗机构检验报告调阅等工作。 在医疗机构间,一方面在区域卫生信息平台上构建区......
  • 一文搞定,PO设计模式详解
    PO模式:全称:pageobjece,分层机制,让不同层去做不同类型的事情,让代码结构清晰,增加复⽤性。PO模式的优势:1)效率⾼:同理,PO模式的逻辑层⽅法有具体定义,情况和元素发⽣变化⼀样修改逻辑层,业务层不变。这样看来结构简单清晰,舒服更符合⼈类习惯,普通⽅式就是继续堆case。2)复⽤多收益⼤:同样......
  • 从追MM谈Java的23种设计模式
    1、FACTORY—追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说“来四个鸡翅”就行了。麦当劳和肯德基就是生产鸡翅的Factory.以下是引用片段:实例一:publicclassFactory{......
  • Redis的淘汰策略
    edis默认的淘汰策略Redis是一款开源的高性能内存数据库,广泛应用于Web应用缓存、消息队列、实时数据分析等领域。在使用Redis时,淘汰策略是其中一个重要的概念,它决定了当Redis内存不足时,被选择删除的key是哪些。Redis的淘汰策略有6种,分别是:1.noevictionnoeviction是默认淘汰策略,即当......