浅析几种设计模式--策略模式

浅析几种设计模式--策略模式

策略模式

策略模式是对算法的包装,把使用算法的责任和算法本身分隔开,委派给不同的对象管理。策略模式通常把一系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。

作用

  1. 算法可独立于使用外部而变化
  2. 客户端方便根据外部条件选择不同策略来解决不同问题

策略模式仅仅封装算法(包括添加 & 删除),但策略模式并不决定在何时使用何种算法,算法的选择由客户端来决定。

实例

背景

有一家百货公司,最近在定年度的促销活动。

冲突

每个节日用同一个促销活动太枯燥,没吸引力

解决方案

针对不同节目使用不同促销活动进行促销

步骤1:

定义抽象策略角色(Strategy):百货公司所有促销活动的共同接口

public abstract class Strategy {  	
    public abstract void showActivity();	
}

步骤2:

定义具体策略角色(Concrete Strategy):

以下是每个具体活动

//为春节准备的促销活动A	
class StrategyA extends Strategy{	
    @Override	
    public void showActivity() {	
        System.out.println("春节促销活动A");	
    }	
}	

//为中秋节准备的促销活动B	
class StrategyB extends Strategy{	

    @Override	
    public void showActivity() {	
        System.out.println("中秋节促销活动B");	
    }	
}	
//为圣诞节准备的促销活动C	
class StrategyC extends Strategy{	

    @Override	
    public void showActivity {	
        System.out.println("圣诞节促销活动C");	
    }	
}

步骤3:

定义环境角色(Context):用于连接上下文,即把促销活动推销给客户,这里可以理解为销售员

class Context_SalesMan{	
    private Strategy strategy;//持有抽象策略角色的引用	

    //生成销售员实例时告诉销售员什么节日(构造方法),使得让销售员根据传入的参数(节日)选择促销活动(这里使用一个简单的工厂模式)	
    public SalesMan(String festival) {	
        switch ( festival) {	
             case "A":    //春节就使用春节促销活动	
                strategy = new StrategyA();	
                break;	
            case "B":   //中秋节就使用中秋节促销活动	
                strategy = new StrategyB();	
                break;	
            case "C":  //圣诞节就使用圣诞节促销活动	
                strategy = new StrategyC();	
                break;	
        }	
    }	

    //向客户展示促销活动	
    public void SalesManShow(){	
        strategy.showActivity();	
    }
}

public class StrategyPattern {	
    public static void main(String[] args){	
        Context_SalesMan mSalesMan ;	

        //春节来了,使用春节促销活动	
        System.out.println("对于春节:");	
        mSalesMan =  new Context_SalesMan("A");	
        mSalesMan.SalesManShow();	

        //中秋节来了,使用中秋节促销活动	
        System.out.println("对于中秋节:");	
        mSalesMan =  new Context_SalesMan("B");	
        mSalesMan.SalesManShow();	

        //圣诞节来了,使用圣诞节促销活动	
        System.out.println("对于圣诞节:");	
        mSalesMan =  new Context_SalesMan("C");	
        mSalesMan.SalesManShow();	
    }
}

总结

优点

  1. 策略类之间可以自由切换
  2. 由于策略类都实现同一个接口,所以使它们之间可以自由切换。
  3. 易于扩展
  4. 增加一个新的策略只需要添加一个具体的策略类即可,基本不需要改变原有的代码,符合“开闭原则”
  5. 避免使用多重条件选择语句(if else),充分体现面向对象设计思想。

缺点

  1. 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
  2. 策略模式将造成产生很多策略类,可以通过使用享元模式在一定程度上减少对象的数量。

策略模式的本质:少用继承,多用组合

Read more

超快速,使用ChatGPT编写回归和分类算法

超快速,使用ChatGPT编写回归和分类算法

本文将使用一些 ChatGPT 提示,这些提示对于数据科学家在工作时非常重要。 微信搜索关注《Python学研大本营》,加入读者群,分享更多精彩 以下是一些示例ChatGPT 提示的列表以及数据科学家的响应。 ChatGPT 提示 为决策树回归算法生成 python 代码。 下面是使用scikit-learn在 Python 中进行决策树回归的示例代码: import numpy as np import matplotlib.pyplot as plt from sklearn.tree import DecisionTreeRegressor # Generate random data rng = np.random.default_rng() x = 5 * rng.random(100) y = np.sin(x) + 0.

By Ne0inhk
力扣每日一题:993.二叉树的堂兄弟节点 深度优先算法

力扣每日一题:993.二叉树的堂兄弟节点 深度优先算法

993.二叉树的堂兄弟节点 难度:简单 题目: 在二叉树中,根节点位于深度 0 处,每个深度为 k 的节点的子节点位于深度 k+1 处。 如果二叉树的两个节点深度相同,但 父节点不同 ,则它们是一对堂兄弟节点。 我们给出了具有唯一值的二叉树的根节点 root ,以及树中两个不同节点的值 x 和 y 。 只有与值 x 和 y 对应的节点是堂兄弟节点时,才返回 true 。否则,返回 false。 示例: 示例 1: 输入:root = [1,2,3,4], x = 4, y = 3 输出:false

By Ne0inhk
1239.串联字符串的最大长度 关于字符串的回溯算法!

1239.串联字符串的最大长度 关于字符串的回溯算法!

题目: 给定一个字符串数组 arr,字符串 s 是将 arr 某一子序列字符串连接所得的字符串, 如果 s 中的每一个字符都只出现过一次,那么它就是一个可行解。 请返回所有可行解 s 中最长长度。 提示: 1 <= arr.length <= 16 1 <= arr[i].length <= 26 arr[i] 中只含有小写英文字母 示例: 示例 1: 输入:arr = ["un","iq","ue"] 输出:4 解释:所有可能的串联组合是

By Ne0inhk