`
zhangweieye
  • 浏览: 9775 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

设计模式学习笔记(四:策略模式)

 
阅读更多

1.1概述

     方法是类中最重要的组成部分,一个方法的方法体由一系列语句构成,也就是说一个方法的方法体是一个算法。在某些设计中,一个类的设计人员经常可能涉及这样的问题:由于用户需求的变化,导致经常需要修改类中某个方法的方法体,即需要不断地变化算法。在这样的情况下可以考虑使用策略模式。

    策略模式是处理算法不同变体的一种成熟模式,策略模式通过接口或抽象类封装算法的标识,即在接口中定义一个抽象方法,实现该接口的类将实现接口中的抽象方法。策略模式把针对一个算法标识的一系列具体算法分别封装在不同的类中,使得各个类给出的具体算法可以相互替换。

    在策略模式中,封装算法标识的接口称作策略,实现该接口的类称作具体策略。

 

1.2模式的结构

    策略模式的结构包括三种角色:

(1)策略(Strategy):策略是一个接口,该接口定义若干个算法标识,即定义了若干个抽象方法。

(2)具体策略(ConcreteStrategy):具体策略是实现策略接口的类。具体策略实现策略接口所定义的抽象方法,即给出算法标识的具体算法。

(3)上下文(Context):上下文是依赖于策略接口的类,即上下文包含有策略声明的变量。上下文中提供了一个方法,该方法委托策略变量调用具体策略所实现的策略接口中的方法。

策略模式接口的类图如下所示:

 

 

 

1.3策略模式的优点

(1)上下文和具体策略是松耦合关系。因此上下文只知道它要使用某一个实现Strategy接口类的实例,但不需要知道具体是哪一个类。

(2)策略模式满足“开-闭原则”。当增加新的具体策略时,不需要修改上下文类的代码,上下文就可以引用新的具体策略的实例。

 

1.4适合使用策略模式的情景

(1)一个类定义了多种行为,并且这些行为在这个类的方法中以多个条件语句的形式出现,那么可以使用策略模式在类中使用大量的条件语句。

(2)程序不希望暴露复杂的、与算法有关的数据结构,那么可以使用策略模式来封装算法。

(3)需要使用一个算法的不同变体。

 

 

1.5策略模式的使用

下面通过一个简单的实例,实现1.1概述中简单例子:在某种比赛中有若干个裁判,每位裁判给选手一个得分。选手的最后得分是根据全体裁判的得分计算出来的。请给出几种计算选手得分的评分方案(策略),对于某次 比赛,可以从你的方案中选择一种方案作为本次比赛的评分方案。

针对上述问题,使用策略模式设计若干个类。具体如下:

首先看一下本实例构建框架具体类和1.2模式的结构中类图的对应关系,如下图所示:

 

 

(1)策略(Strategy

本问题中,策略接口的名字是ComputableStrategy,该接口规定的算法标识即抽象方法是double computeScore(double []a)ComputableStrategy接口的代码如下:

package com.liuzhen.four_strategy;

public interface ComputableStrategy {
    public abstract double computeScore(double[] a);
}

 

(2)具体策略

对于本问题,有三个具体策略StrategyOneStrategyTwoStrategyTree。其中StrategyOne类实现为计算数组a的元素代数平均值;StrategyTwo类实现计算数组a的元素的几何平均值;StrategyThree类实现为去掉数组a中最大元素和最小元素 ,然后计算剩余元素的代数平均值。

StrategyOne类代码如下:

复制代码
package com.liuzhen.four_strategy;

public class StrategyOne implements ComputableStrategy{
    public double computeScore(double[] a){
        double score = 0 , sum = 0;
        for(int i = 0;i < a.length;i++){
            sum += a[i];
        }
        score = sum/a.length;
        return score;
    }
}
复制代码

StrategyTwo类代码如下:

复制代码
package com.liuzhen.four_strategy;

public class StrategyTwo implements ComputableStrategy {

    public double computeScore(double[] a) {
        double score = 0 , multi = 1;
        int n = a.length;
        for(int i = 0;i < a.length;i++){
            multi = multi*a[i];
        }
        score = Math.pow(multi,1.0/n);
        return score;
    }

}
复制代码

StrategyThree类代码如下:

复制代码
package com.liuzhen.four_strategy;

import java.util.Arrays;

public class StrategyThree implements ComputableStrategy{
    public double computeScore(double[] a){
        if(a.length <= 2)
            return 0;
        double score = 0,sum = 0;
        Arrays.sort(a);
        for(int i = 1;i < a.length-1;i++){
            sum += a[i];
        }
        score = sum/(a.length-2);
        return score;
    }
}
复制代码

 

(3)上下文

上下文是GymnasticsGame类,该类包含策略声明的变量,此变量可用于保存具体策略的引用。另外,GymnasticsGame类中包含一个double型数组aa的元素代表各个裁判给选手的评分。该类中的getPersonScore(double a[])方法将委托具体策略的实例计算选手的最后得分。GymnasticsGame类的代码如下:

复制代码
package com.liuzhen.four_strategy;

public class GymnasticsGame {
    ComputableStrategy strategy;
    
    public void setStrategy(ComputableStrategy strategy){
        this.strategy = strategy;
    }
    
    public double getPersonScore(double[] a){
        if(strategy != null)
            return strategy.computeScore(a);
        else
            return 0;
    }
}
复制代码

 

(4)具体使用

复制代码
package com.liuzhen.four_strategy;

public class FourApplication {
    public static void main(String args[]){
        GymnasticsGame game = new GymnasticsGame();       //上下文对象
        game.setStrategy(new StrategyOne());              //上下文对象使用策略一
        Person zhang = new Person();
        zhang.setName("张三");
        double[] a = {9.12,9.25,8.87,9.99,6.99,7.88};
        Person li = new Person();
        li.setName("李四");
        double[] b = {9.15,9.26,8.97,9.89,6.97,7.89};
        zhang.setScore(game.getPersonScore(a));
        li.setScore(game.getPersonScore(b));
        System.out.printf("%s最后得分:%5.3f%n",zhang.getName(),zhang.getScore());
        System.out.printf("%s最后得分:%5.3f%n",li.getName(),li.getScore());
        game.setStrategy(new StrategyTwo());              //上下文对象使用策略二
        zhang.setScore(game.getPersonScore(a));
        li.setScore(game.getPersonScore(b));
        System.out.println("使用几何平均值方案:");
        System.out.printf("%s最后得分:%5.3f%n",zhang.getName(),zhang.getScore());
        System.out.printf("%s最后得分:%5.3f%n",li.getName(),li.getScore());
        game.setStrategy(new StrategyThree());              //上下文对象使用策略三
        zhang.setScore(game.getPersonScore(a));
        li.setScore(game.getPersonScore(b));
        System.out.println("使用(去掉最大值和最小值)算术平均值方案:");
        System.out.printf("%s最后得分:%5.3f%n",zhang.getName(),zhang.getScore());
        System.out.printf("%s最后得分:%5.3f%n",li.getName(),li.getScore());
    }
}
复制代码

其中,Person类代码如下:

复制代码
package com.liuzhen.four_strategy;

public class Person {
    String name;
    double score;
    public void setScore(double score){
        this.score = score;
    }
    public void setName(String name){
        this.name = name;
    }
    public double getScore(){
        return score;
    }
    public String getName(){
        return name;
    }
    
}
复制代码

 

运行结果如下:

复制代码
张三最后得分:8.683
李四最后得分:8.688
使用几何平均值方案:
张三最后得分:8.625
李四最后得分:8.631
使用(去掉最大值和最小值)算术平均值方案:
张三最后得分:8.780
李四最后得分:8.817
复制代码
分享到:
评论

相关推荐

    设计模式学习笔记总结

    这里我们聚焦于C#语言中的设计模式学习笔记,涵盖了多种经典的设计模式,如合成模式、桥梁模式、装饰模式、享元模式、门面模式、命令模式、工厂方法、策略模式、代理模式以及状态模式。下面将对这些模式逐一进行详细...

    HeadFirst 设计模式学习笔记1--策略模式Demo

    《HeadFirst设计模式学习笔记1--策略模式Demo》 在软件工程中,设计模式是一种解决常见问题的标准方案,它提供了一种在特定情况下组织代码的模板。策略模式是设计模式中的一种行为模式,它允许在运行时选择算法或...

    23种设计模式学习笔记

    这个“23种设计模式学习笔记”文档将引导你深入理解这些模式,并帮助你在实际编程中有效地应用它们。以下是对23种设计模式的详细解读: 1. **单例模式**:确保一个类只有一个实例,并提供全局访问点。它常用于控制...

    C#设计模式学习笔记

    以下是对“C#设计模式学习笔记”中涉及的一些关键知识点的详细解释。 1. **设计模式的基本概念**: 设计模式是一种在特定上下文中已被证明有效的解决方案模板,它描述了如何在软件设计中解决常见问题。设计模式...

    23种设计模式学习笔记及源码

    这个压缩包文件包含了23种设计模式的学习笔记和源码,旨在帮助开发者深入理解并熟练运用这些模式。以下是对每种设计模式的详细解释,以及它们在Java编程中的应用。 1. **单例模式**:确保一个类只有一个实例,并...

    设计模式学习笔记

    设计模式的学习不仅帮助我们编写更可维护、可扩展的代码,还能提高团队间的沟通效率,因为它们提供了通用的语言和解决方案。在实际开发中,灵活运用这些设计模式可以有效解决设计问题,提升代码质量。因此,深入理解...

    GoF 23种设计模式学习笔记

    "GoF 23种设计模式学习笔记" 是一个深入探讨这23个经典设计模式的资源,这些模式最初由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位作者在1994年的著作《设计模式:可复用面向对象软件的基础》中...

    Head.First 设计模式学习笔记.pdf

    ### Head.First 设计模式学习笔记知识点总结 #### 一、设计模式概述 设计模式是一种用于解决软件设计中常见问题的标准化方法。通过采用设计模式,开发者可以提高代码的复用性、灵活性和可维护性。《Head First 设计...

    设计模式之美—学习笔记

    在这个“设计模式之美”的学习笔记中,我们将探讨一些主要的设计模式,以及它们在实际开发中的应用。 首先,我们从创建型模式开始。这类模式主要用于对象的创建,如单例模式(Singleton)、工厂模式(Factory ...

    尚硅谷设计模式源码笔记课件.zip

    行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式) 2) 学习目标:通过学习,学员...

    java设计模式学习笔记,以及各种模式的代码实现

    Java设计模式是软件开发中的重要概念,它是一种在特定情境下解决问题的经验总结,可以提高代码的可读性、可维护性和可复用性。这些模式是面向对象编程中的一种最佳实践,通过标准化的方式处理常见的设计问题。下面...

    图解java设计模式_学习笔记_java开发

    这份"图解java设计模式_学习笔记"是针对Java开发者深入理解和应用设计模式的重要资源。在这里,我们将深入探讨Java设计模式的核心概念、分类以及它们在实际开发中的应用。 设计模式分为三大类:创建型、结构型和...

    23中设计模式学习笔记.docx

    ### 23种设计模式学习笔记 #### 一、软件设计模式的概念与意义 **概念:** 软件设计模式(Software Design Pattern),又称设计模式,是一套被广泛采用、经过整理和分类的代码设计经验总结。它针对软件设计过程中...

    300Java设计模式部分学习笔记

    以下是一些在尚学堂300Java设计模式部分学习笔记中涉及的设计模式的知识点: 创建型模式: 创建型模式主要解决对象创建的问题,确保系统的灵活性和封装创建细节。学习笔记中提到了5种创建型模式: 1. 单例模式...

    设计模式笔记

    设计模式是软件工程中的一种重要概念,它代表了在特定情境下解决问题的...设计模式笔记中的内容应该涵盖了以上所述的各种模式,通过深入学习和实践,你可以将这些模式应用到实际项目中,提升自己的编程技能和设计能力。

    《设计模式》学习笔记

    ### 设计模式学习笔记 #### 引言 设计模式(Design Patterns)是在软件设计领域内广泛应用的一种实践指南,它提供了一系列解决常见问题的方案。设计模式可以被理解为面向对象软件设计的经验总结,是对特定面向对象...

    图解设计模式 ,结城浩著 学习笔记

    根据给定的信息“图解设计模式,结城浩著学习笔记”,我们可以推断出这份文档主要涉及了设计模式的学习和理解。《图解设计模式》是一本由日本著名程序员结城浩撰写的书籍,该书以图形化的方式深入浅出地讲解了软件...

Global site tag (gtag.js) - Google Analytics