策略模式 -- 设计模式系列文章(一)

  • 概述

  在日常开发工作中,适当的使用一些设计模式,可以让代码扩展性更强,能更好地拥抱变化,让代码更加优雅。本文主要介绍设计模式中的策略模式,并附上测试示例 Demo 供大家参考。

  • 定义

  策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

  • 个人理解

  策略模式,针对那些动作因对象而异的情况下,把每一个动作都独立封装起来并实现同一个接口,通过组合的方式赋予对象相对应的动作,从而使得所有的动作都可以相互替换。通过策略模式,可以达到在运行时修改对象的具体动作、对象和具体动作之间解耦的效果。

  • 设计原则

  1)找出应用中可能需要变化的地方,把它们独立出来,不要和那些不需要变化的代码混在一起;

  2)面向接口编程,而不是面向实现编程;

  3)多用组合,少用继承;

  • 示例介绍

  这里我以 CF 里面的背包为例子来描述策略模式(有可能 CF 背包的设计不是我讲的这样,这里只是举例说明策略模式)。玩过 CF 的同学都知道,每个角色都有自己的背包,背包里面可以放主武器、副武器、投掷类武器等。而这几类武器,又包含多种具体型号的武器,比如:主武器可以是狙击步枪、冲锋枪,副武器可以是普通手枪、左轮手枪,投掷类武器可以是手雷、烟雾弹、闪光弹等。为了能够达到能够随时调整背包装备的效果,可以采用策略模式。UML 图如下:

  从上面的 UML 可以看出,先定义一个主武器的接口类 IMainArms 和投掷类武器的接口类 IThrowArms,然后让狙击步枪类 SniperRifle 和 冲锋枪类 SubmachineGun 都去实现主武器接口,让手雷类 AntitankGrenade 、闪光弹类 FlashBomb 和 烟雾弹类 SmokeBomb 都去实现投掷类武器接口,接着再在背包类 Pack 中通过 IMainArms 和 IThrowArms 两个接口声明一个主武器变量和一个投掷类武器的变量。至此,在配置背包时,就可以根据实际需要,往背包里面放不同的主武器和不同的投掷类武器,如果有新的主武器或者投掷类武器需要创建,则只需要在创建对应的类时,以相同的方式实现对应的接口后,即可像原有的武器使用方式使用新的武器。

  • 示例代码

  IMainArms 主武器接口

package strategy;

public interface IMainArms {
    void fire();

    void aim();
}

  IThrowArms 投掷类武器接口

package strategy;

public interface IThrowArms {
    void bomb();
}

  SniperRifle 狙击步枪类

package strategy;

public class SniperRifle implements IMainArms {
    private int bulletNum;

    @Override
    public void fire() {
        if(this.bulletNum>0){
            System.out.println("狙击枪扣动扳机...");
            this.bulletNum = this.bulletNum - 1;
        }
    }

    @Override
    public void aim() {
        System.out.println("狙击枪瞄准...");
    }

    public int getBulletNum() {
        return bulletNum;
    }

    public void setBulletNum(int bulletNum) {
        this.bulletNum = bulletNum;
    }

}

  SubmachineGun 冲锋枪类

package strategy;

public class SubmachineGun implements IMainArms {
    private int bulletNum;

    @Override
    public void fire() {
        if(this.bulletNum>0){
            System.out.println("冲锋枪扣动扳机...");
            this.bulletNum = this.bulletNum - 1;
        }
    }

    @Override
    public void aim() {
        System.out.println("冲锋枪瞄准...");
    }

    public int getBulletNum() {
        return bulletNum;
    }

    public void setBulletNum(int bulletNum) {
        this.bulletNum = bulletNum;
    }

}

  AntitankGrenade 手雷类

package strategy;

public class AntitankGrenade implements IThrowArms {
    private boolean isBomb;

    @Override
    public void bomb() {
        System.out.println("手雷爆炸...");
        this.setBomb(true);
    }

    public boolean isBomb() {
        return isBomb;
    }

    public void setBomb(boolean isBomb) {
        this.isBomb = isBomb;
    }

}

  FlashBomb 闪光弹类

package strategy;

public class FlashBomb implements IThrowArms {
    private boolean isBomb;

    @Override
    public void bomb() {
        System.out.println("闪光弹爆炸...");
        this.setBomb(true);
    }

    public boolean isBomb() {
        return isBomb;
    }

    public void setBomb(boolean isBomb) {
        this.isBomb = isBomb;
    }

}

  SmokeBomb 烟雾弹类

package strategy;

public class SmokeBomb implements IThrowArms {
    private boolean isBomb;

    @Override
    public void bomb() {
        System.out.println("烟雾弹爆炸...");
        this.setBomb(true);
    }

    public boolean isBomb() {
        return isBomb;
    }

    public void setBomb(boolean isBomb) {
        this.isBomb = isBomb;
    }

}

  MainTest 测试类

package test;

import strategy.AntitankGrenade;
import strategy.FlashBomb;
import strategy.Pack;
import strategy.SniperRifle;
import strategy.SubmachineGun;

public class MainTest {
    public static void main(String[] args) {
        SniperRifle sniperRifle = new SniperRifle();
        sniperRifle.setBulletNum(100);
        SubmachineGun submachineGun = new SubmachineGun();
        submachineGun.setBulletNum(50);

        AntitankGrenade antitankGrenade = new AntitankGrenade();
        antitankGrenade.setBomb(false);
        FlashBomb flashBomb = new FlashBomb();
        flashBomb.setBomb(false);

        Pack pack1 = new Pack();
        pack1.setMainArms(sniperRifle);
        pack1.setPackNo(1);
        pack1.setThrowArms(antitankGrenade);

        Pack pack2 = new Pack();
        pack2.setMainArms(submachineGun);
        pack2.setPackNo(2);
        pack2.setThrowArms(flashBomb);

        pack1.getMainArms().aim();
        pack1.getMainArms().fire();
        pack1.getThrowArms().bomb();

        pack2.getMainArms().aim();
        pack2.getMainArms().fire();
        pack2.getThrowArms().bomb();
    }
}

欢迎转载,转载必须标明出处

时间: 2025-01-07 13:06:33

策略模式 -- 设计模式系列文章(一)的相关文章

策略模式--设计模式系列

今天我们写一个鸭子类,首先分析一下鸭子有哪些特征呢? 鸭子:会叫,会游水,会飞,外观 现在有个需求:分两种鸭子,一种是外观是绿头,一种是红头,写下看: class Duck: def quack(self): print('呱呱叫') def swim(self): print('我会游泳') def display(self):pass def fly(self): print('我会飞') class RedDuck(Duck): def display(self): print('我是红头

.NET设计模式系列文章

单件模式(Singleton Pattern) Singleton模式要求一个类有且仅有一个实例,并且提供了一个全局的访问点. 工厂方法模式(Factory Method) 定义一个用户创建对象的接口,让子类决定实例化哪一个类. 原型模式(Prototype Pattern) 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象 http://www.cnblogs.com/terrylee/archive/2006/07/17/334911.html .NET设计模式系列文章,布布扣

策略模式设计模式(Strategy)摘录

23种子GOF设计模式一般分为三类:创建模式.结构模型.行为模式. 创建模式抽象的实例.一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化托付给还有一个对象.创建型模式有两个不断出现的主旋律.第一.它们都将关于该系统使用哪些详细的类的信息封装起来.第二,它们隐藏了这些类的实例是怎样被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建.谁创建它.它是怎样被创建的.以及何时创建这些方面

[转].NET设计模式系列文章

最初写探索设计模式系列的时候,我只是想把它作为自己学习设计模式的读书笔记来写,可是写到今天,设计模式带给我的震撼,以及许多初学者朋友的热心支持,让我下定决心要把这个系列写完写好,那怕花上再多的时间也无所谓.本部分内容不断更新中. 目录计划: 第Ⅰ部分 开篇 开篇 第Ⅱ部分 创建型模式篇 第1章 单件模式(Single Pattern) 第2章 抽象工厂模式(Abstract Factory) 第3章 建造者模式(Builder Pattern) 第4章 工厂方法(Factory Method)

策略模式-设计模式

在讲述之前,我们首先看小例子: 现实生活中我们去商场上买东西的时候,卖场经常根据不同的客户来制定不同的报价策略,比如新客户不打折扣,针对老客户打9折,针对VIP打8折…… 现在我们做一个报价管理模块,简要点就是针对不同的客户,提供不同的报价. 假如是有你来做,你会怎么做?在日常的开发中,我们大部分会写出如下的代码片段: public class QuoteManager { public BigDecimal quote(BigDecimal originalPrice,String custo

三分钟理解“策略模式”——设计模式轻松掌握

实际问题: 由于超市隔三差五就要办促销活动,但每次促销活动的方式不一样,所以需要开发一个软件,营业员只要输入原价再选择活动类型后,就能计算出折扣以后的价钱. 普通人的做法: mian(){ String input = readLine(); double price = readLine(); switch (input) case "九五折": price = price * 0.95; break; case "满100返50": if(price>=1

不一样的策略模式(设计模式五)

前言 什么是设计模式?说白了就是套路,是经过历代程序员总结出来的.很多时候我们虽然学会了很多套路,但是啥时候使用,使用哪个合适,我想这才是问题的关键. 知道怎么用不知道什么时候用,这时候看下代码风格也行用的上,策略模式是非常容易通过代码风格使用上的. 策略模式,为什么叫策略模式呢?其实策略模式还有一个别名叫做政策(policy)模式,在古代,对不同的国家呢,实行不同的政策,对A呢,采取税务10%,对B国采取税务20%. 这样根据不同国家政策不同呢,在计算机中就是根据不同对象采取不同的方法,就叫做

云计算设计模式系列文章

云计算设计模式(一)——缓存预留模式 云计算设计模式(二)——断路器模式 云计算设计模式(三)——补偿交易模式 云计算设计模式(四)——消费者的竞争模式 云计算设计模式(五)——计算资源整合模式 云计算设计模式(六)——命令和查询职责分离(CQRS)模式 云计算设计模式(七)——事件获取模式 云计算设计模式(八)——外部配置存储模式 云计算设计模式(九)——联合身份模式 云计算设计模式(十)——守门员模式 云计算设计模式(十一)——健康端点监控模式 云计算设计模式(十二)——索引表模式 云计算设

.NET设计模式系列文章《转》

原文发布时间为:2008-11-02 -- 来源于本人的百度文章 [由搬家工具导入] http://www.cnblogs.com/Terrylee/archive/2006/07/17/334911.html 最初写探索设计模式系列的时候,我只是想把它作为自己学习设计模式的读书笔记来写,可是写到今天,设计模式带给我的震撼,以及许多初学者朋友的热心支持,让我下定决心要把这个系列写完写好,那怕花上再多的时间也无所谓。本部分内容不断更新中。 目录计划: 第Ⅰ部分 开篇 开篇 第Ⅱ部分 创建型模式篇