39策略模式(Strategy Pattern)

算法与对象的耦合:
    对象可能经常需要使用多种不同的算法,但是如果变化频繁,会将类型变得脆弱...
            
动机:
    在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码对象中,将会使对象变得异常复杂;而且有时候支持不使用的算法也是一个性能负担。
    如何在运行时根据需要透明地更改对象的算法?将算法与对象本身解耦,从而避免上述问题?
意图:
    定义一系统的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
                                                                     --------《设计模式》GOF
       
适用性:
    1.许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
    2.需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间/时间权衡的算法。当这些变体实现为一个算法的类层次时[H087],可以使用策略模式。    
    3.算法使用客户不应该知道数据。可使用策略模式以避免暴露复杂的,与算法相关的数据结构。
    4.一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。
代码实现:
    

1   enum SortType
2     {
3         QuickSort,
4         ShellSort,
5         MergeSort,
6     }

 

 1     class Sort
 2     {
 3         public void SortList(SortType s)
 4         {
 5             if (s == SortType.QuickSort)
 6             {
 7                 ProcessA();
 8             }
 9             else if (s == SortType.ShellSort)
10             {
11                 ProcessB();
12             }
13             else if (s == SortType.MergeSort)
14             {
15                 ProcessC();
16             }
17             Console.WriteLine();
18         }
19 
20         protected void ProcessA()
21         {
22             Console.WriteLine("QuickSort List");
23         }
24         protected void ProcessB()
25         {
26             Console.WriteLine("ShellSort List");
27         }
28         protected void ProcessC()
29         {
30             Console.WriteLine("MergeSort List");
31         }
32     }


客户端调用:

 1     class Test
 2     {
 3            public static void Main()
 4            {
 5                Sort sort = new Sort();
 6                sort.SortList(SortType.QuickSort);
 7                sort.SortList(SortType.ShellSort);
 8                sort.SortList(SortType.MergeSort);
 9            }
10     }

    由此可见,由于客户端新增调用方式的选择,就会修改SortType及Sort里的判断语句。在类Sort中会增加if语句的判断,用敏捷软件开发的语言说,你应该闻到了代码的臭味道了,也就是设计模式中说的存在了变化的地方。
   重构以上代码,增加一层中间层来处理变化。类结构如下: 
                 

1    //Stategy  表达抽象算法
2    abstract  class SortStrategy
3     {
4        public abstract void Sort(ArrayList list);
5     }

 

 1    //ConcreteStrategy
 2     class ShellSort :SortStrategy
 3     {
 4         public override void Sort(System.Collections.ArrayList list)
 5         {
 6                  list.Sort(); //no-implement
 7                 Console.WriteLine("ShellSorted List");
 8             
 9         }
10     }

 

1   //ConcreteStrategy
2     class MergeSort :SortStrategy
3     {
4         public override void Sort(System.Collections.ArrayList list)
5         {
6             list.Sort(); //no-implement
7             Console.WriteLine("MergeSort List ");
8         }
9     }

1    //ConcreteStrategy
2     class QuickSort :SortStrategy
3     {
4         public override void Sort(System.Collections.ArrayList list)
5         {
6             list.Sort(); //Default is Quicksort
7             Console.WriteLine("QuickSorted List");
8         }
9     }

 

 1     //Context
 2     class SortdList
 3     {
 4         private ArrayList list = new ArrayList();
 5         private SortStrategy sortstrategy;  //对象组合
 6         public void SetSortStrategy(SortStrategy sortstrategy)
 7         {
 8             this.sortstrategy = sortstrategy;
 9         }
10         public void Add(string name)
11         {
12             list.Add(name);
13         }
14         public void Sort()
15         {
16             sortstrategy.Sort(list);
17             //Display results 
18             foreach (string name in list)
19             {
20                 Console.WriteLine(" " + name);
21             }
22             Console.WriteLine();
23         }
24     }

客户端代码如下:

 1    class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             //Two contexts following different strategies 
 6             SortdList studentRecords = new SortdList();
 7 
 8             studentRecords.Add("Satu");
 9             studentRecords.Add("Jim");
10             studentRecords.Add("Palo");
11             studentRecords.Add("Terry");
12             studentRecords.Add("Annaro");
13 
14             studentRecords.SetSortStrategy(new QuickSort());
15             studentRecords.Sort();
16 
17             studentRecords.SetSortStrategy(new ShellSort());
18             studentRecords.Sort();
19 
20             studentRecords.SetSortStrategy(new MergeSort());
21             studentRecords.Sort();
22 
23             Console.Read();
24         }
25     }

由此可见,更好地满足开放封闭原则。
Strategy模式的几个要点:
    1.Strategy及其子类为组件提供了一系列可重用的算法,从而可以使得类型在运行时方便地根据需要在各个算法之间进行切换。所谓封装算法,支持算法的变化。
    2.Strategy模式提供了用条件判断语句以外的另一种选择,消除条件判断语句,就是在解耦合。含有许多条件判断语句的代码通常都需要Strategy模式。
    3.与State类似,如果Strategy对象没有实例变量,那么各个上下文可以共享同一个Strategy对象,从而节省对象开销。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/438626.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python选择表单_如何使用Python在表单中选择选项?

下面是一些基本用法示例:>>> import mechanize>>> br mechanize.Browser()>>> br.open(http://www.w3schools.com/html/html_forms.asp)表单有一个name属性;但有时它是空的:>>> [f.name for f in br.fo…

40访问者模式(Visitor Pattern)

类层次结构的变化: 类层次结构中可能经常由于引入新的操作,从而将类型变得脆弱... 动机: 在软件构建过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为(方法),如果直接…

ssh中c3p0连接mysql_ssh 中使用c3p0 的连接池配置 | 学步园

applicationContext.xml 文件:xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xmlns:jee"http://www.springframework.org/schema/jee"xsi:schemaLocation"http://www.springframework.org/schema/beans http://www.springframewor…

41状态模式(State Pattern)

对象状态影响对象行为: 对象拥有不同的状态,往往会行使不同的行为... 动机: 在软件构建过程中,某些对象的状态如果改变以及其行为也会随之而发生变化,比如文档处于只读状态,其支…

python中空格属于字符吗_举例说明python中空格是属于字符

python中空格属于字符吗?答案是肯定的,空格在Python中也是属于字符的。案例:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。#!/usr/bin/python# -*- coding: UTF-8 -*-import strings raw_input(input a st…

python如何引发和处理异常_在python3.6中,如何捕捉异常并引发异常以便稍后处理?...

假设我有两个例外:class FooError (Exception):def __init__(self, *args, **kwargs):default_message A foo error has occurred!if not (args or kwargs): args (default_message,)super().__init__(*args, **kwargs)class BarError (Exception):def __init__(s…

2字节十六进制浮点数 qt_Qt之8个字节转化为double小数

首先要理解double的存储方式,具体可查找相关的博客本文实现的是将8个字节(存储为16进制的字符串)转化为对应的double类型double MainWindow::qByteArraytodouble(QString qstr){QByteArray byte;StringToHex(qstr,byte);double result;memcpy(&result, byte.dat…

【转】如何将域中的AD数据导入SharePoint

最近刚装好sharepoint2010,想要研究一下,第一件想做的事就是想把AD中的用户信息导入到SharePoint中。 那现在就来看看我是怎么操作的: 1.打开管理中心 sharepoint是通过“用户配置文件同步服务”来实现同步,所以第一步要开启这个…

Apsara Clouder专项技能认证:实现调用API接口

一.API 简介 1.API 的概念 API(Application Programming Interface应用程序编程接口)是一些预定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码或理解内部工作机制的细节 2.API 的特点 API 是一个明确定义的接口,可以为其…

druid加密mysql_Druid 数据库用户密码加密 代码实现

标签:druid-1.0.16.jar 阿里巴巴的开源数据连接池 jar包明文密码私钥(privateKey)加密加密密码加密密码公钥(publicKey)解密明文密码程序代码如下:package com.t1;import com.alibaba.druid.filter.config.ConfigTools;public class DruidTest {public s…

select switch语句总是搞混,总结如下

select switch语句总是搞混,总结如下 类C:c c c# java : 比较 switch(expression) { case constant-expression : statement(s); break; /* optional */ case constant-expression : statement(s); brea…

java路径怎么找_Java路径怎么找

有一种情况是装好java了,配置好java环境(在Linux里面比较复杂)了,但忘了路径了?!解决:先要申明一下which java是定位不到安装路径的。which java定位到的是java程序的执行路径。网上的资料都是人云亦云,完全…

【转】什么是CORS

CORS 全称是跨域资源共享(Cross-Origin Resource Sharing),是一种 AJAX 跨域请求资源的方式,支持现代浏览器,IE支持10以上。 CORS与JSONP的使用目的相同,但是比JSONP更强大。JSONP只支持GET请求&#xff0c…

java web 连接linux_如何将javaweb项目部署到linux下

以下是对将javaweb项目部署到linux下的方法进行了详细的分析介绍一般都在windows下开发的现在部署到linux下将项目达成war包(用eclipse项目右键>Export>选择war file)将tomcat(用winSCP当然你也可以用secureCRT用securCRT需要建立sftp(即上传文件的目录)用put tomcat命令…

第一节:复习委托,并且通过委托的异步调用开启一个新线程和异步回调、异步等待

一. 再谈委托 1. 委托是一个关键字为delegate的自定义类型,通过委托可以把方法以参数的形式传递给另外一个方法,实现插件式的开发模式; 同时调用委托的时候,委托所包含的所有方法都会被实现。 2. 委托的发展历史:new…

linux 修改 java 内存_Linux 和 Windows修改Java虚拟机内存大小

因为内存溢出问题1. Linux下直接修改%tomcat_home%/bin/catalina.sh文件在注释下紧接一行也就是脚本正文开始之前 加上Java_OPTS-server -Xms512m -Xmx1024m -XX:PermSize128m -XX:MaxPermSize512m如果报-x没有定义,则用declare -x JAVA_OPTS"-Xms512m -Xmx1024"初始…

第二节:深入剖析Thread的五大方法、数据槽、内存栅栏

一. Thread及其五大方法 Thread是.Net最早的多线程处理方式,它出现在.Net1.0时代,虽然现在已逐渐被微软所抛弃,微软强烈推荐使用Task(后面章节介绍),但从多线程完整性的角度上来说,我们有必要了解下N年前多线程的是怎么…

java redis 生成唯一id_Redis在集群环境中生成唯一ID

概述设计目标:每秒最大生成10万个ID,ID单调递增且唯一。Reidis可以不需要持久化ID。要求:集群时钟不能倒退。总体思路:集群中每个节点预生成生成ID;然后与redis的已经存在的ID做比较。如果大于,则取节点生成的ID&#…

java 读取 image_如何在java读取sql里头读取image格式的数据转换成图片格式

一、北亚文件系统数据恢复Windows版可以恢复Windows用户在使用过程中丢失的数据(误删除文件、误格式化硬盘、U盘/手机存储卡数据丢失、误清空回收站、磁盘分区消失)。软件操作简单,易用。可恢复故障:误删除文件:1:可只恢复指定路径…

java await signal_【Java并发008】原理层面:ReentrantLock中 await()、signal()/signalAll()全解析...

一、前言上篇的文章中我们介绍了AQS源码中lock方法和unlock方法,这两个方法主要是用来解决并发中互斥的问题,这篇文章我们主要介绍AQS中用来解决线程同步问题的await方法、signal方法和signalAll方法,这几个方法主要对应的是synchronized中的…