策略模式
含义
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
原理
策略模式定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
代码实现
来玩一个僵尸的游戏 定个规则 僵尸有外貌 ,走路方式 ,攻击方式三种
不用策略模式的代码
package com.hxj.designpattern.strategy.v1;
/**
* ZombieTest
* 策略模式 僵尸游戏
* 策略模式为何要引入 通过游戏可以理解 v2为策略模式的实现改进
*
* @author liuguang
* @date 2021/5/6 14:32
*/
public class ZombieTest {
public static void main(String[] args) {
//第一版本
AbstractZombie normalZombie = new NormalZombie();
AbstractZombie flagZombie = new FlagZombie();
normalZombie.display();
normalZombie.move();
normalZombie.attack();
System.out.println("-------------");
flagZombie.display();
flagZombie.move();
flagZombie.attack();
}
}
/**
* AbstractZombie
* 抽象僵尸类
*
* @author liuguang
* @date 2021/5/6 14:38
*/
abstract class AbstractZombie {
/**
* 展示方法
*/
public abstract void display();
/**
* 攻击模式
*/
public void attack() {
System.out.println("咬");
}
/**
* 移动方式
*/
public void move() {
System.out.println("一步一步移动");
}
}
/**
* NormalZombie
* 普通僵尸实现类
*
* @author liuguang
* @date 2021/5/6 14:39
*/
class NormalZombie extends AbstractZombie {
@Override
public void display() {
System.out.println("我是普通僵尸");
}
}
/**
* FlagZombie
* 骑手僵尸实现类
*
* @author liuguang
* @date 2021/5/6 14:39
*/
class FlagZombie extends AbstractZombie {
@Override
public void display() {
System.out.println("我是棋手僵尸");
}
}
/**
* BigHeadZombie
* 大头僵尸实现
*
* @author liuguang
* @date 2021/5/6 14:41
*/
class BigHeadZombie extends AbstractZombie {
@Override
public void display() {
System.out.println("大头");
}
@Override
public void attack() {
System.out.println("头撞");
}
}
/**
* 某某僵尸 想拥有头撞的攻击方式 但是又不是普通的移动
* 需要重写移动方式 或者其他的一些功能 会导致父类特别复杂
* <p>
* 稳定的是 外观移动跟攻击 变化的是这些方式的实现
*/
class XxxZombie extends BigHeadZombie {
@Override
public void move() {
System.out.println("跳跃着走");
}
}
缺点:某某僵尸 想拥有头撞的攻击方式 但是又不是普通的移动
需要重写移动方式 或者其他的一些功能 会导致父类特别复杂 不断的进行继承
使用策略模式的代码
package com.hxj.designpattern.strategy.v2;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
/**
* StrategyTest
* 策略模式 策略模式主要的意义就是把行为抽象出来成类 通过配置 成员变量的方式去配置策略 形成可以复用
* jdk 源码的实现 Arrays.sort Comparator 排序器
* @author liuguang
* @date 2021/5/6 14:47
*/
public class StrategyTest {
public static void main(String[] args) {
Zombie bigHeadZombie = new BigHeadZombie();
Zombie normalZombie = new NormalZombie();
bigHeadZombie.display();
bigHeadZombie.move();
bigHeadZombie.attack();
//还可以通过set变化
bigHeadZombie.setAttackAble(new AttackAble() {
@Override
public void attack() {
System.out.println("头扩大无数遍就是干");
}
@Override
public void attack2() {
attack();
}
});
bigHeadZombie.attack();
System.out.println("---------------");
normalZombie.display();
normalZombie.move();
normalZombie.attack();
}
}
/**
* 移动接口
*/
interface MoveAble {
void move();
}
/**
* 攻击接口
*/
interface AttackAble {
void attack();
void attack2();
}
/**
* 抽象僵尸接口
*/
@Getter
@Setter
@AllArgsConstructor
abstract class Zombie {
/**
* 外观
*/
abstract public void display();
/**
* 成员变量移动
*/
MoveAble moveAble;
/**
* 成员变量攻击
*/
AttackAble attackAble;
abstract void move();
abstract void attack();
}
/**
* 普通僵尸
*/
class NormalZombie extends Zombie {
/**
* 无参构造传递策略类
*/
public NormalZombie() {
super(new StepByStepMove(),new BiteAttack());
}
public NormalZombie(MoveAble moveAble, AttackAble attackAble) {
super(moveAble, attackAble);
}
@Override
public void display() {
System.out.println("我是普通僵尸");
}
@Override
void move() {
moveAble.move();
}
@Override
void attack() {
attackAble.attack();
}
}
/**
* 大头僵尸
*/
class BigHeadZombie extends Zombie {
public BigHeadZombie() {
super(new StepByStepMove(),new BigHeadAttack());
}
public BigHeadZombie(MoveAble moveAble, AttackAble attackAble) {
super(moveAble, attackAble);
}
@Override
public void display() {
System.out.println("我是大头僵尸");
}
@Override
void move() {
moveAble.move();
}
@Override
void attack() {
attackAble.attack();
}
}
/**
* 移动策略实现类 一步一步
*/
class StepByStepMove implements MoveAble{
@Override
public void move() {
System.out.println("一步一步移动");
}
}
/**
* 攻击策略实现类 咬
*/
class BiteAttack implements AttackAble{
@Override
public void attack() {
System.out.println("咬");
}
@Override
public void attack2() {
attack();
}
}
/**
* 攻击策略实现类 头撞
*/
class BigHeadAttack implements AttackAble{
@Override
public void attack() {
System.out.println("头撞");
}
@Override
public void attack2() {
attack();
}
}
优点: 把策略进行封装成类 实现了可以复用 跟 随时修改
个人理解
策略模式其实就是把策略抽象出来成为一个类 ,通过成员变量注入的方法实现策略模式的复用性,还有可替换性