设计模式-策略模式,模板方法模式练习

本文通过一个飞机模拟系统的案例,展示了如何运用策略模式来实现不同飞机类型的起飞和飞行行为。文章详细介绍了如何创建一个抽象飞机类Air,以及不同类型的飞机(如直升机、客机、歼击机和鹞式战斗机)的实现。在测试部分,利用Map存储飞机类型与类的关系,并根据输入参数启动相应飞机的飞行过程。总结中提到,策略模式结合工厂模式能有效解决策略选择问题,而模板方法模式则有助于按顺序执行复杂操作。
摘要由CSDN通过智能技术生成

 看了刘伟老师的设计模式里面的策略模式,做一下后面的练习题。算法的封装与切换——策略模式(四)_刘伟技术博客-CSDN博客史上最全设计模式导学目录(完整版)_刘伟技术博客-CSDN博客

 

练习

    Sunny软件公司欲开发一款飞机模拟系统,该系统主要模拟不同种类飞机的飞行特征与起飞特征,需要模拟的飞机种类及其特征如表24-1所示:

      为将来能够模拟更多种类的飞机,试采用策略模式设计该飞机模拟系统。
 

 

 表24-1 飞机种类及特征一览表

 首先分析问题,首先具体对象是飞机, 飞机有不同的种类(直升机,客机,歼击机,鹞式战斗机),然后飞机有两个动作,一个是起飞,一个是飞行,不同种类的飞机这两个动作会有不同的特征。这里我们定义一个抽象类Air , 定义3个方法 起飞takeOff(), 飞行fly(), 开始飞行 startFly();其中开始飞行方法里面调用起飞和飞行(这里用到的是就是模板方法模式模板方法模式深度解析(一)_刘伟技术博客-CSDN博客_模板方法模式)。

这里还可以细分,一次完整的飞行操作包括:起飞,飞行,降落3个步骤。还可以把降落方法定义出来,放在:开始飞行 startFly() 里面。

package com.pattern.strategy.abs;

public abstract class Air {
    protected String name;

    public Air(String name) {
        this.name = name;
    }

    /**
     * 起飞
     */
    public abstract void takeOff();

    /**
     * 飞行
     */
    public abstract void fly();
    //降落
    public void land(){
        System.out.println(name + "降落!");
    }
    /**
     * 开始飞行
     */
    public void startFly(){
        System.out.println(name + "开始飞行!");
        takeOff();
        fly();
        land();
    }
}

然后定义不同的飞机,飞机继承Air

package com.pattern.strategy;

import com.pattern.strategy.abs.Air;
//客机
public class AirPlane extends Air {

    public AirPlane(String name) {
        super(name);
    }

    @Override
    public void takeOff() {
        System.out.println(name + "长距离起飞(LongDistanceTakeOff)");
    }

    @Override
    public void fly() {
        System.out.println(name + "亚音速飞行(SubSonicFly)");
    }
}
//歼击机
public class Fighter extends Air {

    public Fighter(String name) {
        super(name);
    }

    @Override
    public void takeOff() {
        System.out.println(name + "长距离起飞(LongDistanceTakeOff)");
    }
    @Override
    public void fly() {
        System.out.println(name + "超音速飞行(SuperSonicFly)");
    }
}
//鹞式战斗机
public class Harrier extends Air {

    public Harrier(String name) {
        super(name);
    }

    @Override
    public void takeOff() {
        System.out.println(name + "垂直起飞(VerticalTakeOff)");
    }

    @Override
    public void fly() {
        System.out.println(name + "超音速飞行(SuperSonicFly)");
    }
}
//直升机
public class Helicopter extends Air {

    public Helicopter(String name) {
        super(name);
    }

    @Override
    public void takeOff() {
        System.out.println(name + "垂直起飞VerticalTakeOff");
    }
    @Override
    public void fly() {
        System.out.println(name + "亚音速飞行(SubSonicFly)");
    }
}

定义好后可以测试了:在测试这里定义了一个Map来存储飞机和类之间的关系,通过main函数里面的参数args来传入具体飞机,

package com.pattern.strategy;

import com.pattern.strategy.abs.Air;

import java.util.HashMap;
import java.util.Map;

public class Client {
    public static void main(String[] args){
        if(args.length == 0){
            System.out.println("飞机名称不正确");
            return;
        }
        Map<String,String> airMap = new HashMap<>();
        airMap.put("直升机","com.pattern.strategy.Helicopter");
        airMap.put("客机","com.pattern.strategy.AirPlane");
        airMap.put("歼击机","com.pattern.strategy.Fighter");
        airMap.put("鹞式战斗机","com.pattern.strategy.Harrier");
        String name = args[0];
        String className = airMap.get(name);
        if(className == null){
            System.out.println("飞机名称不正确");
            return;
        }
        try {
            //找到飞机对应的class
            Class clazz = Class.forName(className);
            //创建飞机对象
            Air air = (Air) clazz.getDeclaredConstructor(String.class).newInstance(name);
            //飞机起飞
            air.startFly();
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("飞机事故");
        }

    }
}

传入具体参数:

 运行结果:

直升机开始飞行!
直升机垂直起飞VerticalTakeOff
直升机亚音速飞行(SubSonicFly)
直升机降落!

总结:策略模式和工厂模式一起用能比较容易的解决策略的选择问题。同一件事如果需要按照顺序执行不同的步骤,可以使用模板方法模式来实现。

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值