一、游戏角色技能释放策略
-
策略模式引入背景
在一个奇幻角色扮演游戏里,游戏角色拥有多样技能,像英勇战士的 “强力斩击”“盾牌格挡”,敏捷刺客的 “隐匿突袭”“飞刀绝技”,神秘法师的 “火焰冲击”“冰霜禁锢”。若用传统写法,在角色类的技能释放方法中,会充斥大量if - else判断,例如:
class GameCharacter {
String characterType;
void releaseSkill() {
if ("Warrior".equals(characterType)) {
if ("强力斩击".equals(skillName)) {
// 执行战士强力斩击逻辑,如挥剑造成高额伤害,有特殊动画效果
System.out.println("战士挥出强力一剑,造成巨额伤害!");
} else if ("盾牌格挡".equals(skillName)) {
// 举起盾牌,降低所受伤害,改变角色防御姿态
System.out.println("战士举起盾牌,坚如磐石,格挡攻击!");
}
} else if ("Assassin".equals(characterType)) {
// 刺客技能判断及执行逻辑类似,十分繁琐冗长
//...
} else if ("Mage".equals(characterType)) {
// 法师技能判断及执行逻辑类似,代码不断堆砌
//...
}
}
}
这种结构随着技能和角色类型增多,代码极难维护与扩展。
-
策略模式应用
-
策略接口定义:先创建
SkillReleaseStrategy接口,规范技能释放行为。
-
interface SkillReleaseStrategy {
void release();
}
-
具体策略类实现:
-
战士强力斩击策略类:
-
class WarriorPowerSlashStrategy implements SkillReleaseStrategy {
@Override
public void release() {
System.out.println("战士紧握巨剑,凝聚全身力量,向前猛力挥出,剑刃划过空气,造成 500 点伤害,触发炫酷斩击特效!");
}
}
-
战士盾牌格挡策略类:
class WarriorShieldBlockStrategy implements SkillReleaseStrategy {
@Override
public void release() {
System.out.println("战士迅速将盾牌立于身前,盾牌泛起微光,吸收 80%的外来伤害,自身进入防御强化状态。");
}
}
-
刺客隐匿突袭策略类:
class AssassinStealthStrikeStrategy implements SkillReleaseStrategy {
@Override
public void release() {
System.out.println("刺客隐身潜入敌阵,瞬间现身,从敌人背后发动致命一击,造成 400 点暴击伤害,附带流血效果。");
}
}
- 上下文类设置:游戏角色类作为上下文,持有策略接口引用,灵活切换策略。
class GameCharacter {
private SkillReleaseStrategy skillReleaseStrategy;
public GameCharacter(SkillReleaseStrategy skillReleaseStrategy) {
this.skillReleaseStrategy = skillReleaseStrategy;
}
public void setSkillReleaseStrategy(SkillReleaseStrategy skillReleaseStrategy) {
this.skillReleaseStrategy = skillReleaseStrategy;
}
public void releaseSkill() {
skillReleaseStrategy.release();
}
}
- 使用示例
public class Game {
public static void main(String[] args) {
// 创建战士角色并设置强力斩击策略
GameCharacter warrior = new GameCharacter(new WarriorPowerSlashStrategy());
warrior.releaseSkill();
// 切换为盾牌格挡策略
warrior.setSkillReleaseStrategy(new WarriorShieldBlockStrategy());
warrior.releaseSkill();
// 创建刺客角色并释放隐匿突袭技能
GameCharacter assassin = new GameCharacter(new AssassinStealthStrikeStrategy());
assassin.releaseSkill();
}
}
二、电商商品促销定价策略
- 策略模式引入背景
电商平台的商品定价在促销期间复杂多变,日常按原价销售,到促销季,有满减(如满 200 减 50)、折扣(打 8 折)、赠品(买一送一)等多种策略。传统编码在计算商品最终价格方法里,满是if - else区分促销类型。
class Product {
String promotionType;
double originalPrice;
double calculateFinalPrice() {
if ("满减".equals(promotionType)) {
// 满减逻辑,判断金额是否达标,计算减免后价格
//...
} else if ("折扣".equals(promotionType)) {
// 折扣逻辑,按比例计算折后价
//...
} else if ("赠品".equals(promotionType)) {
// 赠品价值评估及价格处理逻辑
//...
}
return originalPrice;
}
}
新增促销策略就得反复修改该方法,易出错且难维护。
-
策略模式应用
- 策略接口定义:定义
PromotionPricingStrategy接口。
- 策略接口定义:定义
interface PromotionPricingStrategy {
double calculatePrice(double originalPrice);
}
-
具体策略类实现:
- 满减策略类:
class FullReductionStrategy implements PromotionPricingStrategy {
private final int fullAmount;
private final int reductionAmount;
public FullReductionStrategy(int fullAmount, int reductionAmount) {
this.fullAmount = fullAmount;
this.reductionAmount = reductionAmount;
}
@Override
public double calculatePrice(double originalPrice) {
if (originalPrice >= fullAmount) {
return originalPrice - reductionAmount;
}
return originalPrice;
}
}
- 折扣策略类:
class DiscountStrategy implements PromotionPricingStrategy {
private final double discountRate;
public DiscountStrategy(double discountRate) {
this.discountRate = discountRate;
}
@Override
public double calculatePrice(double originalPrice) {
return originalPrice * discountRate;
}
}
-
赠品策略类:为简化示例,赠品策略暂按赠品价值占商品价值一定比例估算对价格影响(实际可复杂得多)。
class GiftStrategy implements PromotionPricingStrategy {
private final double giftValueRate;
public GiftStrategy(double giftValueRate) {
this.giftValueRate = giftValueRate;
}
@Override
public double calculatePrice(double originalPrice) {
return originalPrice * (1 - giftValueRate);
}
}
- 上下文类设置:商品类作为上下文,关联促销策略。
class Product {
private PromotionPricingStrategy promotionPricingStrategy;
private double originalPrice;
public Product(PromotionPricingStrategy promotionPricingStrategy, double originalPrice) {
this.promotionPricingStrategy = promotionPricingStrategy;
this.originalPrice = originalPrice;
}
public void setPromotionPricingStrategy(PromotionPricingStrategy promotionPricingStrategy) {
this.promotionPricingStrategy = promotionPricingStrategy;
}
public double calculateFinalPrice() {
return promotionPricingStrategy.calculatePrice(originalPrice);
}
}
- 使用示例
public class ECommerce {
public static void main(String[] args) {
// 商品原价 300,使用满减策略(满 200 减 50)
Product product1 = new Product(new FullReductionStrategy(200, 50), 300);
System.out.println("满减后价格: " + product1.calculateFinalPrice());
// 商品原价 250,使用折扣策略(8 折)
Product product2 = new Product(new DiscountStrategy(0.8), 250);
System.out.println("折扣后价格: " + product2.calculateFinalPrice());
// 商品原价 100,使用赠品策略(赠品价值占商品 20%)
Product product3 = new Product(new GiftStrategy(0.2), 100);
System.out.println("考虑赠品后价格: " + product3.calculateFinalPrice());
}
}
三、图形绘制形状绘制策略
- 策略模式引入背景
图形绘制软件要绘制多种形状,像矩形、圆形、三角形等,若用常规单一方法处理,代码会这样:
class GraphicsDrawer {
String shapeType;
void draw() {
if ("矩形".equals(shapeType)) {
// 绘制矩形逻辑,确定四个顶点坐标,连线成矩形
//...
} else if ("圆形".equals(shapeType)) {
// 绘制圆形逻辑,以圆心和半径画圆
//...
} else if ("三角形".equals(shapeType)) {
// 绘制三角形逻辑,确定三个顶点坐标,连线成三角形
//...
}
}
}
每新增形状,就要在 draw 方法里加大量新逻辑,导致代码臃肿杂乱。
-
策略模式应用
- 策略接口定义:定义
ShapeDrawingStrategy接口。
- 策略接口定义:定义
interface ShapeDrawingStrategy {
void drawShape();
}
-
具体策略类实现:
- 矩形绘制策略类:
class RectangleDrawingStrategy implements ShapeDrawingStrategy {
@Override
public void drawShape() {
System.out.println("确定矩形左上角坐标 (x1,y1) 和右下角坐标 (x2,y2),依次连接 (x1,y1)、(x2,y1)、(x2,y2)、(x1,y2) 四点,绘制出矩形。");
}
}
- 圆形绘制策略类:
class CircleDrawingStrategy implements ShapeDrawingStrategy {
@Override
public void drawShape() {
System.out.println("以给定圆心坐标 (x0,y0) 和半径 r,利用数学公式,围绕圆心绘制圆周,形成圆形。");
}
}
- 三角形绘制策略类:
class TriangleDrawingStrategy implements ShapeDrawingStrategy {
@Override
public void drawShape() {
System.out.println("确定三角形三个顶点坐标 (x1,y1)、(x2,y2)、(x3,y3),依次连接三点,绘制出三角形。");
}
}
- 上下文类设置:绘图类作为上下文,管理绘制策略。
class GraphicsDrawer {
private ShapeDrawingStrategy shapeDrawingStrategy;
public GraphicsDrawer(ShapeDrawingStrategy shapeDrawingStrategy) {
this.shapeDrawingStrategy = shapeDrawingStrategy;
}
public void setShapeDrawingStrategy(ShapeDrawingStrategy shapeDrawingStrategy) {
this.shapeDrawingStrategy = shapeDrawingStrategy;
}
public void draw() {
shapeDrawingStrategy.drawShape();
}
}
- 使用示例
public class GraphicsApp {
public static void main(String[] args) {
// 绘制矩形
GraphicsDrawer drawer1 = new GraphicsDrawer(new RectangleDrawingStrategy());
drawer1.draw();
// 绘制圆形
GraphicsDrawer drawer2 = new GraphicsDrawer(new CircleDrawingStrategy());
drawer2.draw();
// 绘制三角形
GraphicsDrawer drawer3 = new GraphicsDrawer(new TriangleDrawingStrategy());
drawer3.draw();
}
}
四、文件加密解密策略
- 策略模式引入背景
文件处理工具常需加密解密操作,支持多种算法,如对称加密的 AES、DES,非对称加密的 RSA。传统做法在加密解密方法里,靠if - else区分算法。
class FileProcessor {
String encryptionAlgorithm;
byte[] fileData;
byte[] processFile() {
if ("AES".equals(encryptionAlgorithm)) {
// AES 加密解密逻辑,加载密钥,调用加密库方法
//...
} else if ("DES".equals(encryptionAlgorithm)) {
// DES 加密解密逻辑,类似操作,不同算法参数
//...
} else if ("RSA".equals(encryptionAlgorithm)) {
// RSA 加密解密逻辑,公私钥处理等复杂步骤
//...
}
return fileData;
}
}
切换或新增算法,代码修改麻烦,维护困难。
-
策略模式应用
- 策略接口定义:定义
FileEncryptionStrategy接口。
- 策略接口定义:定义
interface FileEncryptionStrategy {
byte[] process(byte[] fileData);
}
-
具体策略类实现:
- AES 加密策略类:假设已引入对应加密库,简化展示核心逻辑。
class AesEncryptionStrategy implements FileEncryptionStrategy {
private final byte[] key;
public AesEncryptionStrategy(byte[] key) {
this.key = key;
}
@Override
public byte[] process(byte[] fileData) {
// 利用 AES 算法和密钥对文件数据加密,返回加密后数据
System.out.println("使用 AES 算法和给定密钥对文件数据进行加密操作。");
return encryptedData;
}
}
- DES 加密策略类:
class DesEncryptionStrategy implements FileEncryptionStrategy {
private final byte[] key;
public DesEncryptionStrategy(byte[] key) {
this.key = key;
}
@Override
public byte[] process(byte[] fileData) {
// DES 加密操作,类似 AES,按自身算法规则处理
System.out.println("利用 DES 算法与密钥加密文件数据。");
return encryptedData;
}
}
- RSA 加密策略类:
class RsaEncryptionStrategy implements FileEncryptionStrategy {
private final byte[] publicKey;
public RsaEncryptionStrategy(byte[] publicKey) {
this.publicKey = publicKey;
}
@Override
public byte[] process(byte[] fileData) {
// 使用 RSA 公钥加密数据,适配公钥加密流程
System.out.println("凭借 RSA 公钥对文件数据开展加密处理。");
return encryptedData;
}
}
-
上下文类设置:文件处理器类作为上下文,操控加密策略。
class FileProcessor {
private FileEncryptionStrategy fileEncryptionStrategy;
private byte[] fileData;
public FileProcessor(FileEncryptionStrategy fileEncryptionStrategy, byte[] fileData) {
this.fileEncryptionStrategy = fileEncryptionStrategy;
this.fileData = fileData;
}
public void setFileEncryptionStrategy(FileEncryptionStrategy fileEncryptionStrategy) {
this.fileEncryptionStrategy = fileEncryptionStrategy;
}
public byte[] processFile() {
return fileEncryptionStrategy.process(fileData);
}
}
- 使用示例
public class FileTool {
public static void main(String[] args) {
byte[] sampleData = "这是一段示例文件数据".getBytes();
// 使用 AES 加密
byte[] aesKey = generateAesKey(); // 假设存在生成密钥方法
FileProcessor processor1 = new FileProcessor(new AesEncryptionStrategy(aesKey), sampleData);
byte[] encryptedData1 = processor1.processFile();
System.out.println("AES 加密后数据: " + Arrays.toString(encryptedData1));
// 使用 DES 加密
byte[] desKey = generateDesKey();
FileProcessor processor2 = new FileProcessor(new DesEncryptionStrategy(desKey), sampleData);
byte[] encryptedData2 = processor2.processFile();
System.out.println("DES 加密后数据: " + Arrays.toString(encryptedData2));
// 使用 RSA 加密
byte[] rsaPublicKey = getRsaPublicKey();
FileProcessor processor3 = new FileProcessor(new RsaEncryptionStrategy(rsaPublicKey), sampleData);
byte[] encryptedData3 = processor3.processFile();
System.out.println("RSA 加密后数据: " + Arrays.toString(encryptedData3));
}
}
通过这些丰富多样且带详细代码的示例,能清晰看到策略模式在不同场景下将复杂逻辑拆解、提升代码可维护与扩展性的强大优势。