参考:https://www.cnblogs.com/lewis0077/p/5133812.html(深入解析策略模式)

定义:

策略模式定义了一系列的算法,并将每一个算法封装起来,使每个算法可以相互替代,使算法本身和使用算法的客户端分割开来,相互独立。

结构:(书中的图,侵删)

1.一个定义公共方法的接口

2.若干实现了接口的具体实现

3.上下文context,用于跟客户端和策略之间交互

实例:

经过我的思考,我感觉上一篇的简单工厂模式使用的计算器的例子,似乎用在这里更为恰当吧。
我们的目的是选择不同的算法,而不是创建不同的对象。
但其实两者的表现形式很像,只是用途不同。
 
所以,我这里继续用计算器的例子。(书中用的是商户采取不同的优惠策略的例子)

公共接口:

package designpattern.strategy;

public interface Calculate {
public double calculate(double num1, double num2);
}

具体实现(加减乘除方法):

package designpattern.strategy;

public class Plus implements Calculate {

    @Override
public double calculate(double num1, double num2) {
return num1 + num2;
} }
package designpattern.strategy;

public class Minus implements Calculate {

    @Override
public double calculate(double num1, double num2) {
return num1 - num2;
} }
package designpattern.strategy;

public class Multiply implements Calculate {

    @Override
public double calculate(double num1, double num2) {
return num1 * num2;
} }
package designpattern.strategy;

public class Divide implements Calculate {

    @Override
public double calculate(double num1, double num2) {
return num1 / num2;
} }

上下文:

package designpattern.strategy;

public class CalculateContext {
Calculate calculate; public CalculateContext(Calculate calculate) {
super();
this.calculate = calculate;
} public double calculate(double num1, double num2) {
return calculate.calculate(num1, num2);
}
}

客户端:

package designpattern.strategy;

import java.util.Scanner;

public class Calculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个数字");
double num1 = scanner.nextDouble();
System.out.println("请输入一个运算符:+、-、*、/");
String operator = scanner.next();// 不能用nextLine(),会把上一个回车给吸收
System.out.println("请输入一个数字");
double num2 = scanner.nextDouble(); switch (operator) {
case "+":
System.out.println(new CalculateContext(new Plus()).calculate(num1, num2));
break;
case "-":
System.out.println(new CalculateContext(new Minus()).calculate(num1, num2));
break;
case "*":
System.out.println(new CalculateContext(new Multiply()).calculate(num1, num2));
break;
case "/":
System.out.println(new CalculateContext(new Divide()).calculate(num1, num2));
break;
default:
break;
} scanner.close();
}
}

这样的写法,还是把判断的任务交给了客户端。

可以稍加改善,把判断交给上下文context。

上下文:

package designpattern.strategy;

public class CalculateContext2 {
Calculate calculate; public CalculateContext2(String operate) {
super();
switch (operate) {
case "+":
this.calculate = new Plus();
break;
case "-":
this.calculate = new Minus();
break;
case "*":
this.calculate = new Multiply();
break;
case "/":
this.calculate = new Divide();
break;
}
} public double calculate(double num1, double num2) {
return calculate.calculate(num1, num2);
}
}

客户端:

package designpattern.strategy;

import java.util.Scanner;

public class Calculator2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个数字");
double num1 = scanner.nextDouble();
System.out.println("请输入一个运算符:+、-、*、/");
String operator = scanner.next();// 不能用nextLine(),会把上一个回车给吸收
System.out.println("请输入一个数字");
double num2 = scanner.nextDouble(); System.out.println(new CalculateContext2(operator).calculate(num1, num2)); scanner.close();
}
}

这里使用了简单工厂模式的思想,传入一个参数,不管具体细节,获得所期望的对象,所以算是简单工厂模式和策略模式的结合。

总结:

策略模式能将我们从if-else中解放出来,当我们需要不停的写if-else的时候,可以想起策略模式。让我们的代码可扩展且更易于维护。

设计模式 | 策略模式(strategy)的更多相关文章

  1. [.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型)

    [.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模 ...

  2. 设计模式--策略模式(strategy)

    1.策略模式(strategy ['strætədʒi]) 我的理解是:方案候选模式 (反正关键就是有很多的候选,哈哈) 看了很多例子,都是在说鸭子的,那个例子很好,在这里可以看 他们生产鸭子,我们就 ...

  3. 设计模式 - 策略模式(Strategy Pattern) 具体解释

    策略模式(Strategy Pattern) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26577879 本文版权全 ...

  4. java设计模式 策略模式Strategy

    本章讲述java设计模式中,策略模式相关的知识点. 1.策略模式定义 策略模式,又叫算法簇模式,就是定义了不同的算法族,并且之间可以互相替换,此模式让算法的变化独立于使用算法的客户.策略模式属于对象的 ...

  5. 设计模式——策略模式(Strategy Pattern)

    写在前面: 直接将书中的例子用来作为记录自己学习的成果,不知道这样好不好,如果给原作者带来什么不利的影响不妨告知一声,我及时删掉. UML图: 抽象策略:Strategy package com.cn ...

  6. 说说设计模式~策略模式(Strategy)

    返回目录 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.而对于客户端(UI)来说,可以通过IOC再配合工厂模块,实现动态策略的切换,策略模块通常于一个抽象策略对象(in ...

  7. C#设计模式——策略模式(Strategy Pattern)

    一.概述我们来实现一个企业的工资系统,该企业中不同级别的员工工资算法都不相同,针对该问题,最容易想到的莫过于在代码中堆积一大堆if…else…语句或者是switch…case…语句.如果该企业中不同级 ...

  8. 设计模式-策略模式Strategy以及消灭if else

    概述 如果在开发过程中,出现大量的if else或者switch case 语句,如果这些语句块中的代码并不是包含业务逻辑,只是单纯的分流方法,那么,每一个语句块中都是一个算法或者叫策略. 背景 比如 ...

  9. 设计模式---策略模式Strategy(对象行为型)

    1. 概述 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化. 策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不 ...

  10. 大话设计模式--策略模式 strategy -- C++实现实例

    1. 策略模式: 它定义了算法家族, 分别封装起来,使他们之间可以相互替换,此模式让算法变化, 不会影响到使用算法的客户. 用相同的方法调用不同的算法,减少各种算法类与使用算法类之间的耦合. 实例中策 ...

随机推荐

  1. 学unity3d需要什么基础

    学unity3d需要什么基础?在游戏业发展如火如荼的情境下,很多人开始转行投身于游戏程序开发,而unity3D游戏开发则是他们必须了解和会用的游戏开发工具.在学习之前又应该了解哪些内容呢? unity ...

  2. 使用DOS命令关闭tomcat端口(其他服务也是可以的)

    废话不多说,直接上步骤: WIN+R 打开DOS窗口 输入netstat -ano|findstr 8080(其中8080是我自己tomcat的端口号) 之后可以看到端口号的最后会有数字,这个数字是端 ...

  3. facenet 进行人脸识别测试

    1.简介:facenet 是基于 TensorFlow 的人脸识别开源库,有兴趣的同学可以扒扒源代码:https://github.com/davidsandberg/facenet 2.安装和配置 ...

  4. python3 爬去QQ音乐

    import requests import re import json import os def get_name(singer): url = 'https://c.y.qq.com/soso ...

  5. 计算机网络相关:应用层协议(二):HTTP

    前言 复习下计算机网络的知识并记录 正文 定义:HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传送协议. 一.HTT ...

  6. Python Web(Django)与SQL SERVER的连接处理

    (开开心心每一天~ ---虫瘾师) Python Web(Django) 与SQL SERVRE的连接----Come QQ群:607021567(里面有很多开源代码和资料,并且python的游戏也有 ...

  7. 你不知道的JavaScript--Item5 全局变量

    1.尽量少用全局对象 全局变量的问题在于,你的JavaScript应用程序和web页面上的所有代码都共享了这些全局变量,他们住在同一个全局命名空间,所以当程序的两个不同部分定义同名但不同作用的全局变量 ...

  8. Python数据运算

    身份运算 is is是判断两个标识符是不是引用自一个对象 x is y, 如果id(x)等于id(y), is 返回结果1 is not is not 是判断两个标识符是不是引用自不同对象 x is ...

  9. upload.go

    package api import (     "os"     "bytes"     "mime/multipart"     &qu ...

  10. 【小白学C#】浅谈.NET中的IL代码

    一.前言 前几天群里有位水友提问:”C#中,当一个方法所传入的参数是一个静态字段的时候,程序是直接到静态字段拿数据还是从复制的函数栈中拿数据“.其实很明显,这和方法参数的传递方式有关,如果是引用传递的 ...