7 常用设计模式之策略模式

本文主要讲解Java设计模式之策略模式

策略模式介绍

策略模式也叫政策模式,是一种行为型设计模式,也是父类与子类关系的一种模式。策略模式采用了面向对象的继承和多态机制。策略模式是定义了一系列宣发并将算法封装起来,使他们可以互相替换,且算法的变化不会影响到使用算法的客户。需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计一个抽象类(可有可无,属于辅助类),提供辅助函数。

策略模式使用场景

1、多个类只有在算法或行为上稍有不同的场景。
2、算法需要自由切换的场景。
3、需要屏蔽算法规则的场景。

策略模式UML图如下:

在这里插入图片描述说明:

Context:也叫做上下文角色,起承上启下封装作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。

Strategy:策略、算法家族的抽象。通常为接口,定义每个策略或算法必须具有的方法和属性。是策略的抽象。

ConreateStrategy:具体的策略实现。该类含有具体的算法。

策略模式使用实例

一批货物从A地运送到距离为500KM 的B地,有三种运送方式,选择一个比较便宜的方式,通过调研有如下三种方式:
分别是飞机、汽车、火车。三种方式价格不一样,飞机每千米50元,汽车是0.5元,火车是0.1元。下面就用策略模式实现下这三种方式分别的费用

1 Strategy,新建一个CalculateStragegy接口

//计算接口
public interface CalculateStrategy {
    float price(int km);
 }

2、ConcreteStrategy,新建CarStrategy,PlaneStrategy、TrainStrategy实现接口CalculateStrategy

//汽车
ublic class CarStrategy implements CalculateStrategy {
        @Override
        public float price(int km) {
            return (float) 0.5 * km;
        }
    }
//飞机
public class PlaneStrategy implements CalculateStrategy {
     @Override
    public float price(int km) {
        return 50 * km;
    }
       }
//火车
 public class TrainStrategy implements CalculateStrategy {
        @Override
        public float price(int km) {
            return (float) (0.1 * km);
        }
    }

3 Context ,新建Client

 public class Client {
    CalculateStrategy calculateStrategy;
    static int km = 500;

    public static void main(String[] args) {
        Client client = new Client();
        //飞机的方式
        client.setCalculateStrategy(new PlaneStrategy());
        System.out.println("乘坐飞机需要的费用为:¥" + client.getPrice(km));
        //火车的方式
        client.setCalculateStrategy(new TrainStrategy());
        System.out.println("乘坐火车需要的费用为:¥" + client.getPrice(km));
        //汽车的方式
        client.setCalculateStrategy(new CarStrategy());
        System.out.println("自己驾车需要的费用为:¥" + client.getPrice(km));
    }

    /**
     * 设置运输方式
     *
     * @param calculateStrategy
     */
    public void setCalculateStrategy(CalculateStrategy calculateStrategy) {
        this.calculateStrategy = calculateStrategy;
    }

    /**
     * 获得费用
     *
     * @param km
     * @return
     */
    public float getPrice(int km) {
        return calculateStrategy.price(km);
    }

策略模式优缺点

优点
1、算法可以自由切换。
2、结构清晰明了,使用简单直观。
3、操作封装更为彻底,简化了操作。
4、耦合度大大降低,只要实现接口即可,无需做其它修改。

缺点
1、随着策略的增加,策略类会越来越多
2、所有的策略都要暴露出去

策略模式的拓展

1、定义一个枚举类,实现方式如下:

public enum Calculator {
    //汽车
    CAR {
        public float price(int km) {
            return (float) 0.5 * km;
        }
    },
    PLANE {//飞机

        public float price(int km) {
            return (float) 50 * km;
        }
    },
    TRAIN {//火车

        public float price(int km) {
            return (float) 0.1 * km;
        }
    };

    Calculator() {

    }

    public abstract float price(int km);
 }

2、修改client

public class Client {
     static int km = 500;

     public static void main(String[] args) {
         System.out.println("乘坐飞机需要的费用为:¥" + Calculator.PLANE.price(km));
         System.out.println("乘坐火车需要的费用为:¥" + Calculator.TRAIN.price(km));
         System.out.println("自己驾车需要的费用为:¥" + Calculator.CAR.price(km));
     }
 }

可以看出:

该例子的Calculator是一个枚举。

Calculator是一个浓缩了策略模式的枚举。

注意:
策略枚举是一个非常优秀和方便的模式,但是其受到枚举类型的限制,每个枚举项都是public、final、static的,拓展性受到了一定的约束,因此在开发中,枚举策略一般担当不了经常发生改变的角色。

猜你喜欢

转载自blog.csdn.net/damokelisijian866/article/details/102771615