【设计模式】行为型模式其九: 策略模式行为型模式其九: 《策略模式》 生活实例 当我们出行旅游时, 可以选择多种出行方式

发布时间:2024-12-03 13:58

使用旅行模式或全景模式,拍出大场景 #生活技巧# #创意技巧# #旅行拍照攻略#

【设计模式】行为型模式其九: 策略模式

行为型模式其九: 《策略模式》

生活实例

image.png

当我们出行旅游时, 可以选择多种出行方式。 每一种出行方式都达到了目的,具体选择哪种取决于游客当前的想法和包包里的money。

策略模式概述

分析

实现某个目标的途径不止一条,可根据实际情况选择一条合适的途径

软件开发:

多种算法,例如排序、查找、打折等 使用硬编码(Hard Coding)实现将导致系统违背开闭原则,扩展性差,且维护困难 可以定义一些独立的类来封装不同的算法,每一个类封装一种具体的算法

策略模式定义

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

又称为政策(Policy)模式

每一个封装算法的类称之为策略(Strategy)类

策略模式提供了一种可插入式(Pluggable)算法的实现方案

策略模式结构

image.png

策略模式包含以下3个角色:

Context(环境类) Strategy(抽象策略类) ConcreteStrategy(具体策略类)

策略模式实例介绍

问题: 某软件公司为某电影院开发了一套影院售票系统,在该系统中需要为不同类型的用户提供不同的电影票打折方式,具体打折方案如下:

(1) 学生凭学生证可享受票价8折优惠。

(2) 年龄在10周岁及以下的儿童可享受每张票减免10元的优惠(原始票价需大于等于20元)。

(3) 影院VIP用户除享受票价半价优惠外还可进行积分,积分累计到一定额度可换取电影院赠送的礼品。

该系统在将来可能还要根据需要引入新的打折方式。

现使用策略模式设计该影院售票系统的打折方案。

抽象策略类代码

// 这里接口用于定义打折方式

//折扣类:抽象策略类 public interface Discount { public double calculate(double price); }

具体策略类代码

//学生票折扣类:具体策略类

public class StudentDiscount implements Discount { private final double DISCOUNT = 0.8; public double calculate(double price) { System.out.println("学生票:"); return price * DISCOUNT; } }

//VIP会员票折扣类:具体策略类

public class VIPDiscount implements Discount { private final double DISCOUNT = 0.5; public double calculate(double price) { System.out.println("VIP票:"); System.out.println("增加积分!"); return price * DISCOUNT; } }

//儿童票折扣类:具体策略类

public class ChildrenDiscount implements Discount { private final double DISCOUNT = 10; public double calculate(double price) { System.out.println("儿童票:"); if(price>=20) { return price - DISCOUNT; } else { return price; } } }

环境类

环境类(Context)的作用是将具体策略类(Concrete Strategy)封装起来,并提供一些对外接口,使得客户端可以通过环境类使用不同的具体策略类,从而实现不同的行为。环境类包含一个策略类的引用,客户端通过调用环境类的方法来执行相应的策略。

如果不使用环境类,客户端必须直接与具体策略类交互,这样会使得客户端和具体策略类之间的耦合度增加,不利于系统的扩展和维护。同时,如果需要切换不同的策略,客户端必须自己负责管理策略之间的关系,这样会增加客户端的复杂度。

//电影票类:环境类 public class MovieTicket { private double price; private Discount discount; //维持一个对抽象折扣类的引用 // 输入初始价格 public void setPrice(double price) { this.price = price; } //注入一个折扣类对象 public void setDiscount(Discount discount) { this.discount = discount; } public double getPrice() { //调用折扣类的折扣价计算方法 return discount.calculate(this.price); } }

同样的,为了不修改源代码,我使用XML配置文件

XML配置文件

提醒一下: 里面写的是类的包路径加类名,为了jvm能读取到

<?xml version="1.0"?> <config> <className>designpatterns.strategy.VIPDiscount</className> </config>

XMLUtil读取

public class XMLUtil { //该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象 public static Object getBean() { try { //创建DOM文档对象 DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = dFactory.newDocumentBuilder(); Document doc; doc =builder.parse(new File("./config.xml")); //获取包含类名的文本节点 NodeList nl = doc.getElementsByTagName("className"); Node classNode=nl.item(0).getFirstChild(); String cName=classNode.getNodeValue(); //通过类名生成实例对象并将其返回 Class c=Class.forName(cName); Object obj=c.getConstructor().newInstance(); return obj; } catch(Exception e) { e.printStackTrace(); return null; } } }

客户端测试

public class Client { public static void main(String args[]) { MovieTicket mt = new MovieTicket(); double originalPrice = 60.0; double currentPrice; mt.setPrice(originalPrice); System.out.println("原始价为:" + originalPrice); System.out.println("---------------------------------"); Discount discount; discount = (Discount)XMLUtil.getBean(); //读取配置文件并反射生成具体折扣对象 mt.setDiscount(discount); //注入折扣对象 currentPrice = mt.getPrice(); System.out.println("折后价为:" + currentPrice); } }

输出:

原始价为:60.0
VIP票:
增加积分!
折后价为:30.0

当我们想要使用不同的策略文件,就只需修改配置文件。

策略模式优缺点

模式优点:

提供了对开闭原则的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为 提供了管理相关的算法族的办法 提供了一种可以替换继承关系的办法 可以避免多重条件选择语句 提供了一种算法的复用机制,不同的环境类可以方便地复用策略类

模式缺点:

客户端必须知道所有的策略类,并自行决定使用哪一个策略类 将造成系统产生很多具体策略类 无法同时在客户端使用多个策略类

模式适用环境

一个系统需要动态地在几种算法中选择一种 避免使用难以维护的多重条件选择语句 不希望客户端知道复杂的、与算法相关的数据结构,提高算法的保密性与安全性

本文收录于以下专栏

专讲Java版本的设计模式,详细且附代码,还有知识点补充。

网址:【设计模式】行为型模式其九: 策略模式行为型模式其九: 《策略模式》 生活实例 当我们出行旅游时, 可以选择多种出行方式 https://www.yuejiaxmz.com/news/view/360618

相关内容

行为型设计模式之策略模式(Strategy)
策略模式实现旅游出行策略
设计模式:策略(Strategy)模式
设计模式之策略模式实例
C++ 设计模式之策略模式
【设计模式】策略模式 ( 简介
设计模式:生活中的策略模式
重学 Java 设计模式:实战策略模式「模拟多种营销类型优惠券,折扣金额计算策略场景」
说说策略模式在我们生活的场景?
多模式出行场景下差异化激励绿色出行策略研究

随便看看