设计模式之策略模式例题:根据用户等级算积分的接口

server/2024/10/20 6:36:36/

问题

问题:写一个根据游戏用户等级来送赠送积分的方法接口,一共有100个等级,每种等级都有一个方法,使用策略模式
在设计一个根据游戏用户等级来赠送积分的接口时,我们需要考虑几个关键点:

解决

性能:对于大量用户或频繁的操作,接口应该能够高效地处理请求。
可扩展性:随着游戏的更新或新的等级系统引入,接口应该能够容易地扩展。
易读性和维护性:代码应该清晰、易于理解,并易于维护。

基于上述考虑,以下使用策略模式

策略模式定义了一系列的算法,并将每一个算法封装起来,使它们可以互相替换。策略模式使得算法可以独立于使用它的客户变化。对于这个问题,我们可以为每一个等级定义一个赠送积分的策略。这样,当我们需要改变某个等级的积分赠送规则时,我们只需要修改那个等级的策略,而不需要修改整个接口。

python__12">python 示例代码:

首先,定义一个策略接口:

python">from abc import ABC, abstractmethodclass RewardStrategy(ABC):@abstractmethoddef calculate_reward(self, user):pass

然后,为每个等级实现具体的策略类:

python">class Level1Reward(RewardStrategy):def calculate_reward(self, user):return 10  # 假设等级1的用户获得10积分class Level2Reward(RewardStrategy):def calculate_reward(self, user):return 20  # 假设等级2的用户获得20积分# ... 为其他等级实现策略类 ...class Level100Reward(RewardStrategy):def calculate_reward(self, user):return 1000  # 假设等级100的用户获得1000积分

接下来,定义一个奖励计算器,它使用策略模式

python">class RewardCalculator:def __init__(self):self.strategies = {1: Level1Reward(),2: Level2Reward(),# ... 为其他等级添加策略对象 ...100: Level100Reward(),}def get_reward(self, user):level = user.levelstrategy = self.strategies.get(level)if strategy:return strategy.calculate_reward(user)else:return 0  # 或者抛出异常,表示无效的等级

最后,使用这个奖励计算器:

python">class User:def __init__(self, level):self.level = levelcalculator = RewardCalculator()
user = User(1)  # 假设用户等级为1
reward = calculator.get_reward(user)
print(f"User with level {user.level} received {reward} points.")

这种设计方法的优点在于:

性能:由于我们为每个等级预先定义了策略对象,因此查找和计算奖励的时间复杂度是O(1)。
可扩展性:如果需要添加新的等级或修改某个等级的规则,我们只需要添加或修改相应的策略类,而不需要修改其他代码。
易读性和维护性:每个等级的规则都被封装在单独的类中,使得代码更加清晰和易于维护。

C++示例

在C++中,抽象类和抽象方法的实现略有不同。C++使用= 0来标记一个纯虚函数(即抽象方法),并使用class关键字后加上abstract来声明一个抽象类(在C++11及以后的版本中,这并非强制性的,因为只要类中含有纯虚函数,它就是抽象的)。以下是将您提供的Python抽象类RewardStrategy转换为C++代码的示例:

#include <iostream>
#include <memory> // for std::unique_ptr// 抽象类 RewardStrategy,包含纯虚函数 calculate_reward
class RewardStrategy {
public:virtual ~RewardStrategy() = default; // 虚析构函数,确保正确释放派生类对象// 纯虚函数,需要在派生类中实现virtual int calculate_reward(const User& user) const = 0;
};// 假设有一个User类,其中包含level属性
class User {
public:User(int level) : level_(level) {}int getLevel() const { return level_; }private:int level_;
};// 具体的策略类,继承自 RewardStrategy 并实现纯虚函数
class Level1Reward : public RewardStrategy {
public:int calculate_reward(const User& user) const override {return 10; // 假设等级1的用户获得10积分}
};class Level2Reward : public RewardStrategy {
public:int calculate_reward(const User& user) const override {return 20; // 假设等级2的用户获得20积分}
};// ... 可以为其他等级实现类似的策略类 ...// 奖励计算器类,使用策略模式
class RewardCalculator {
public:// 假设有一个map来存储等级到策略的映射std::map<int, std::unique_ptr<RewardStrategy>> strategies;RewardCalculator() {// 初始化策略映射strategies[1] = std::make_unique<Level1Reward>();strategies[2] = std::make_unique<Level2Reward>();// ... 为其他等级添加策略对象 ...}int getReward(const User& user) {auto it = strategies.find(user.getLevel());if (it != strategies.end()) {return it->second->calculate_reward(user);} else {return 0; // 或者可以抛出异常,表示无效的等级}}
};int main() {User user(1); // 假设用户等级为1RewardCalculator calculator;int reward = calculator.getReward(user);std::cout << "User with level " << user.getLevel() << " received " << reward << " points." << std::endl;return 0;
}

在C++代码中,我们使用了std::map来存储每个等级对应的策略对象的唯一指针(std::unique_ptr)。std::unique_ptr是C++11引入的智能指针,用于自动管理对象的生命周期。我们还在RewardStrategy类中添加了虚析构函数,以确保在删除派生类对象时,它们的析构函数也会被正确调用。

此外,C++中的纯虚函数使用= 0来标记,并在派生类中使用override关键字来明确表示我们是要重写基类的虚函数。const关键字用于表明calculate_reward函数不会修改其参数或类的任何成员变量,且返回值也不依赖于任何对象的可变状态。

请注意,这个示例假设User类已经存在,并且有一个getLevel方法来获取用户的等级。您可能需要根据实际情况调整User类的定义。

总结


http://www.ppmy.cn/server/4953.html

相关文章

使用pdfbox将pdf转换成图片

导入pom文件 <dependency><groupId>org.apache.pdfbox</groupId><artifactId>fontbox</artifactId><version>2.0.22</version></dependency><dependency><groupId>org.apache.pdfbox</groupId><artifact…

学习前端第二十一天(循环:while,for)

一、while 循环 while (condition) { // 代码&#xff0c;所谓的“循环体” } 当 condition 为真时&#xff0c;执行循环体的代码。 二、do...while 循环 do { // 循环体 } while (condition); 循环首先执行循环体&#xff0c;然后检查条件&#xff0c;当条件为真时&…

React-hooks:useReducer

useReducer 文档地址 useReducer 是一个 React Hook&#xff0c;它允许你向组件里面添加一个 reducer。 对于拥有许多状态更新逻辑的组件来说&#xff0c;过于分散的事件处理程序可能会令人不知所措。对于这种情况&#xff0c;你可以将组件的所有状态更新逻辑整合到一个外部函…

解决Linux根分区空间不足的方法:利用Home分区进行扩容

前言 在进行系统安装时&#xff0c;一个常见的困扰是默认分区设置可能导致home分区拥有过多的空间&#xff0c;而root分区却显得十分紧缺。这种情况下&#xff0c;用户往往会陷入无法继续安装软件或存储文件的困境。本文将向您展示如何通过合理的调整&#xff0c;将home分区中多…

Java 中解释器模式,请用代码具体举例

解释器模式是一种行为设计模式&#xff0c;用于解释语言或表达式。它定义了一种语言的语法&#xff0c;并提供了解释器来解释该语言中的表达式。以下是一个简单的 Java 示例&#xff0c;演示了解释器模式的用法&#xff1a; import java.util.Map; import java.util.Stack; imp…

PLC中连接外部现场设备和CPU的桥梁——输入/输出(I/O)模块

输入&#xff08;Input&#xff09;模块和输出&#xff08;Output&#xff09;模块简称为I/O模块&#xff0c;数字量&#xff08;Digital&#xff0c;又称为开关量&#xff09;输入模块和数字量输出模块简称为DI模块和DQ模块&#xff0c;模拟量&#xff08;Analog&#xff09;输…

Docker Compose 的安装和使用详解

Docker Compose 是 Docker 官方开源的容器编排(Orchestration)项目之一,用于快速部署分布式应用。本文将介绍 Docker Compose 的基本概念、安装流程及使用方法。 简介 Compose 项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。从功能上看,Docker C…

部署ELFK+zookeeper+kafka架构

目录 前言 一、环境部署 二、部署ELFK 1、ELFK ElasticSearch 集群部署 1.1 配置本地hosts文件 1.2 安装 elasticsearch-rpm 包并加载系统服务 1.3 修改 elasticsearch 主配置文件 1.4 创建数据存放路径并授权 1.5 启动elasticsearch是否成功开启 1.6 查看节点信息 …