首页 > 其他分享 >策略模式

策略模式

时间:2023-10-15 23:55:11浏览次数:25  
标签:策略 void System 模式 Override println public out

策略模式

案例引入

duck项目

要求:
1.有各种鸭子,比如野鸭,北京鸭,水鸭等,鸭子有各种行为,比如叫,飞行。
2.显示鸭子的信息。

传统方式实现案例

1.抽象一个父类duck,有其子类,野鸭、北京鸭、水鸭等。

代码
/**
 * @author 长名06
 * @version 1.0
 */
public abstract class Duck {

    public Duck(){

    }

    public abstract void display();

    public void quack(){
        System.out.println("鸭子嘎嘎叫");
    }

    public void swim(){
        System.out.println("鸭子会游泳");
    }

    public void fly(){
        System.out.println("鸭子会飞翔");
    }

}
/**
 * @author 长名06
 * @version 1.0
 */
public class ToyDuck extends Duck{
    @Override
    public void display() {
        System.out.println("这是玩具鸭");
    }

    @Override
    public void swim() {
        System.out.println("玩具鸭不能游泳");
    }

    @Override
    public void fly() {
        System.out.println("玩具鸭不能飞");
    }

    @Override
    public void quack() {
        System.out.println("玩具鸭不能叫");
    }
}
/**
 * @author 长名06
 * @version 1.0
 */
public class WildDuck extends Duck{
    @Override
    public void display() {
        System.out.println("这是野鸭");
    }
}
/**
 * @author 长名06
 * @version 1.0
 */
public class BeJingDuck extends Duck{
    @Override
    public void display() {
        System.out.println("这是北京鸭");
    }

    //覆盖父类的fly方法
    @Override
    public void fly() {
        System.out.println("北京鸭不能飞翔");
    }
}
传统实现问题分析
  • 1.其它鸭子,都继承了Duck类,所以fly让所有子类都会飞了,这是不正确的。
  • 2.问题1其实是继承的问题,对类的局部改动,尤其超类的局部改动,会影响其他部分。有溢出效应。
  • 3.为了改进1问题,我们可以覆盖fly方法,来解决
  • 4.如果我们有一个玩具鸭子ToyDuck,这样就需要ToyDuck去覆盖Duck的所有实现方法 => 解决思路 策略模式(Strategy Pattern)

基本介绍

  • 1.策略模式(Strategy Pattern)中,定义算法簇,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的用户。
  • 2.此模式,体现了几种设计原则。第一,将变化的代码从不变的代码分离;第二,针对接口编程而不是具体的类(定义策略模式接口);第三,多用组合/聚合,少用继承(客户通过组合方式使用策略)。

原理类图


说明:从上图可以看到,客户Context,有成员变量strategy或者其他的策略接口,至于需要使用到那个策略,我们可以在构造器中指定。

策略模式实现案例

uml图

代码实现
/**
 * @author 长名06
 * @version 1.0
 */
public abstract class Duck {

    //属性,策略接口
    FlyBehavior flyBehavior;

    public Duck(){

    }


    public abstract void display();

    public void quack(){
        System.out.println("鸭子嘎嘎叫");
    }

    public void swim(){
        System.out.println("鸭子会游泳");
    }

    public void fly(){
        if(flyBehavior != null){
            flyBehavior.fly();
        }
    }

    public void setFlyBehavior(FlyBehavior flyBehavior) {
        this.flyBehavior = flyBehavior;
    }
}
/**
 * @author 长名06
 * @version 1.0
 */
public interface FlyBehavior {

    void fly();

}
/**
 * @author 长名06
 * @version 1.0
 */
public class GoodFlyBehavior implements FlyBehavior{
    @Override
    public void fly() {
        System.out.println("飞翔技术很好");
    }
}
/**
 * @author 长名06
 * @version 1.0
 */
public class NoFlyBehavior implements FlyBehavior{
    @Override
    public void fly() {
        System.out.println("不会飞");
    }
}
/**
 * @author 长名06
 * @version 1.0
 */
public class BadFlyBehavior implements FlyBehavior{
    @Override
    public void fly() {
        System.out.println("飞翔技术还行");
    }
}
/**
 * @author 长名06
 * @version 1.0
 */
public class ToyDuck extends Duck {

    public ToyDuck(){
        flyBehavior = new NoFlyBehavior();
    }

    @Override
    public void display() {
        System.out.println("这是玩具鸭");
    }

    @Override
    public void swim() {
        System.out.println("玩具鸭不能游泳");
    }

    @Override
    public void quack() {
        System.out.println("玩具鸭不能叫");
    }
}
/**
 * @author 长名06
 * @version 1.0
 */
public class WildDuck extends Duck {

    public WildDuck() {
        flyBehavior = new GoodFlyBehavior();
    }

    @Override
    public void display() {
        System.out.println("这是野鸭");
    }
}
/**
 * @author 长名06
 * @version 1.0
 */
public class BeJingDuck extends Duck {

    public BeJingDuck(){
        flyBehavior = new BadFlyBehavior();
    }

    @Override
    public void display() {
        System.out.println("这是北京鸭");
    }

}

策略模式在JDK-Arrays类的应用

1.JDK的Arrays的Comparator就使用了策略模式。

核心代码
      Integer[] date = {1, 8, 3, 4, 2, 9};

        //1.实现降序排列,返回-1放左边,1放右边,0保持不变
        //2.comparator就是实现了 Comparator接口的匿名内部类的对象 相当于策略接口的实现类
        //3.public int compare(Integer o1, Integer o2) 制定了具体的处理方式
        Comparator<Integer> comparator = new Comparator<Integer>() {
            public int compare(Integer o1, Integer o2) {
                if(o1 > o2){
                    return 1;
                }else{
                    return -1;
                }
            }
        };

        /**
         *  public static <T> void sort(T[] a, Comparator<? super T> c) {
         *         if (c == null) {
         *             sort(a);//默认方法
         *         } else {
         *             if (LegacyMergeSort.userRequested)
         *                 legacyMergeSort(a, c);//使用策略对象c
         *             else
         *                 TimSort.sort(a, 0, a.length, c, null, 0, 0);//使用策略对象c
         *         }
         *     }
         */
        Arrays.sort(date,comparator);

        System.out.println(Arrays.toString(date));
		
		//使用Lambda表达式方式
        Arrays.sort(date,(var1,var2) -> {
            if(var1.compareTo(var2) > 0){
                return 1;
            }else {
                return -1;
            }
        });
        System.out.println(Arrays.toString(date));

注意事项和细节

  • 1.策略模式的关键是,分析项目中变化部分和不变部分。
  • 2.策略模式的核心思想是,多用组合/聚合,少用继承,用行为类组合。
  • 3.体现了对修改关闭,对扩展开放原则,客户端增加行为不用修改原有代码,只要添加一种策略(或者行为)即可,避免了使用多种分支语句。
  • 4.提供了可以替换继承的方法,策略模式将算法独立封装在Strategy类中使得可以独立于使用者,是算法本身易于切换,理解,扩展。
  • 5.需要注意,添加一个策略,就要增加一个类,策略过多,就会导致类数目庞大。

只是为了记录自己的学习历程,且本人水平有限,不对之处,请指正。

标签:策略,void,System,模式,Override,println,public,out
From: https://www.cnblogs.com/changming06/p/17766467.html

相关文章

  • 桥接模式--Java实现
    画类图具体代码实现//Road.javapackageorg.example.design007;publicabstractclassRoad{publicvoidsetVehicle(Vehiclevehicle){this.vehicle=vehicle;}protectedVehiclevehicle;publicabstractvoiddrive();}//LiQing.ja......
  • 对设计模式的理解
    一切设计,都围绕着抽象与具体展开!大道至简!抽象:一般指接口。里面没有方法细节,只有方法签名。方法签名告诉你它能干什么,但不提供怎么干具体:所有具体类都应该是单一职责的。具体可以依赖抽象,程序运行过程中,会有该抽象的具体实现替代抽象。且具体类要符合最少知道原则,只开放必要的方......
  • 适配器模式--Java实现
    画类图设计一个双向适配器,让猫也能学狗叫,够也能学猫抓老鼠具体代码实现//Cat.javapackageorg.example.design006;publicinterfaceCat{publicvoidmiao();publicvoidzhua();}//Dog.javapackageorg.example.design006;publicinterfaceDog{pu......
  • 单例模式--Java实现
    画类图具体代码实现//StudentNo.javapackageorg.example.design005;publicclassStudentNo{privatestaticStudentNoinstance=null;privateStudentNo(){}publicstaticStudentNogetInstance(){if(instance==null){System.ou......
  • 设计模式 (2):8 种结构性模式
    回顾上节:随着对象种类、属性容量的扩大,创建具体对象、管理属性装配、快速复制等,都面临难题,这时产生了工厂、建造者、原型等设计模式;单例模式也保护了全局变量,提高了全局访问、使用全局对象和接口的安全性、规范性、可用性等等目录1适配器模式(Adapter)方法依赖别的接......
  • Easysearch压缩模式深度比较:ZSTD+source_reuse的优势分析
    引言在使用Easysearch时,如何在存储和查询性能之间找到平衡是一个常见的挑战。Easysearch具备多种压缩模式,各有千秋。本文将重点探讨一种特别的压缩模式:zstd+source_reuse,我们最近重新优化了source_reuse,使得它在吞吐量和存储效率方面都表现出色。测试概览测试条件选用了esr......
  • Easysearch压缩模式深度比较:ZSTD+source_reuse的优势分析
    引言在使用Easysearch时,如何在存储和查询性能之间找到平衡是一个常见的挑战。Easysearch具备多种压缩模式,各有千秋。本文将重点探讨一种特别的压缩模式:zstd+source_reuse,我们最近重新优化了source_reuse,使得它在吞吐量和存储效率方面都表现出色。测试概览测试条件选用了......
  • MPI广播聚合通信模式代码
    #include<mpi.h>#include<stdio.h>#include<unistd.h>intmain(intargc,char**argv){MPI_Init(&argc,&argv);intrank;intsize;MPI_Comm_rank(MPI_COMM_WORLD,&rank);//获取当前进程的rankMPI_Comm_size(MPI_......
  • 线程之间的通信&线程池&设计模式
    day19_线程之间的通信&线程池&设计模式课程目标1.【理解】线程通信概念2.【理解】等待唤醒机制3.【理解】线程池运行原理4.【理解】voliate关键字5.【掌握】单例设计模式线程之间通信什么是线程之间的通信**概念:**多个线程在处理同一个资源,但是处理的动作(线程的任......
  • 原型模式--Java实现
    画类图浅克隆:深克隆:具体代码实现浅克隆具体代码://Vector.javapackageorg.example.design004;importjava.lang.reflect.Array;importjava.util.Arrays;publicclassVectorimplementsCloneable{publicint[]getArray(){returnarray;}......