许多情况下,在一个对象中完成某项任务存在有多种不同的策略。例如,有一个类Sorter对数组进行排序,排序的策略有很多种,实现不同策略排序的一种解决方案是通过类来继承。例如:
public class Sorter {
public List<Object> sort(List<Object> listTobeSorted) {
List<Object> sortedList = null;
// do sort
return sortedList;
}
}
public class SorterA extends Sorter {
public List<Object> sort(List<Object> listTobeSorted) {
List<Object> sortedList = null;
// do sort using strategy A
return sortedList;
}
}
public class SorterB extends Sorter {
public List<Object> sort(List<Object> listTobeSorted) {
List<Object> sortedList = null;
// do sort using strategy B
return sortedList;
}
}
这些类之间的唯一区别是他们排序的策略不一样。另一种方式是为不同的排序策略定义单独的类,然后将这个类传递给Sorter,在Sorter中只需要根据这个策略来完成排序。
/**
*
*/
package design.patterns.strategy;
import java.util.List;
/**
* @author Brandon B. Lin
*
*/
public class Sorter {
private Comparator strategy;
public Sorter(Comparator strategy) {
this.strategy = strategy;
}
public void setStrategy(Comparator strategy) {
this.strategy = strategy;
}
public List<Object> sort(List<Object> listTobeSorted) {
List<Object> sortedList = null;
// do sort using strategy
return sortedList;
}
}
public interface Comparator {
public int compareTo(Object obaject, Object another);
}
public class ComparatorA implements Comparator {
@Override
public int compareTo(Object obaject, Object another) {
return 0;
}
}
public class ComparatorB implements Comparator {
@Override
public int compareTo(Object obaject, Object another) {
// TODO Auto-generated method stub
return 0;
}
}
现在,我们可以使用Comparator对Sorter进行配置,以实现不同排序算法,事实上,我们甚至可以在程序运行的时候改变排序策略(通过setStrategy方法),这是继承无法做到的。当然,也可以将排序任务全部委托给策略,而在Sorter类中简单地调用策略的排序方法。
策略模式的类图如下:
下面是一个来自StackOverFlow的例子,实现不同的认证策略:
public class AuthenticationHandlerImpl implements AuthenticationHandler {
private Authenticator authenticator;
void authenticate() throws ConnectionException {
authenticator.authenticate();
};
public void setAuthenticator(final Authenticator authenticator){
this.authenticator = authenticator;
}
}
interface Authenticator {
void authenticate();
void setLogin(String login);
void setPassword(String password);
}
class URLAuthenticator implements Authenticator {
public void authenticate() {
//use URLConnection
};
}
class HTTPClientAuthenticator implements Authenticator {
public void authenticate() {
//use HTTPClient
};
}
在Java API中,有许多地方都用到了策略模式。事实上java.util.Arrays提供的数组排序方法就用到了策略模式,其中一个方法声明如下:
public static <T> void sort(T[] a, Comparator<? super T> c)
其中,传递的参数Comparator就是策略。
在Java Swing中,容器类的布局也是通过策略模式来实现的。比如,对于JFrame,可以通过setLayout(LayoutManager manager)来配置布局管理器,如果不这么做,我们可能就要继承JFrame来实现不同的布局,比如FlowJFrame实现流布局,GridJFrame实现网格布局。
在URL中,也用到了策略模式。对于不同协议的URL,如http,ftp,如何读取服务器返回的数据,必须遵循相应的协议。因此,通过策略URLStreamHandler来实现对不同协议的流内容的处理,URLStreamHandler根据协议产生相应的URLConnection,然后使用URLConnection读取数据流中的内容。只不过在这里,策略的Java自动帮我们完成,Java根据URL协议部分自动选择合适的URLStreamHandler来处理流,可以通过几成这个类来实现对自定义协议的支持。
策略模式与命令模式有着很微妙的区别。
策略对象可以采用工厂方法模式来创建,或者通过享元模式(Flyweight)来共享。
分享到:
相关推荐
策略模式结合模板方法模式
策略模式的 C++ 代码实现, ide :XCode
策略模式定义了方法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。 还可以那家咖啡屋,记忆里很温馨,很sugar,或许很多温馨美好的回忆都是于咖啡有关的。 我们常常说设计...
所有模式都可分为类模式和对象模式两种,类模式是继承,对象模式是委托,而桥接模式和策略模式都是将任务委托给另外一个接口去实现,那么两者的区别什么呢?
主要介绍了详解SpringBoot结合策略模式实战套路,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
技术: 1. spring事件驱动(ApplicationEventPublisher) 2. 策略模式处理事件 目的: 1. 通过event,代码逻辑异步处理 2. 通过策略模式,构建具体监听实现 3. 解耦 4. 容错(降低代码块错误风险)
这是策略模式中的一个经典实例,通过鸭子问题,能让学习者更好的了解设计模式,这也是headfirst 设计模式中用的经典实例
深入浅出设计模式之抽象工厂模式+工厂方法模式+策略模式实现手机加工厂(加类图)
策略模式实例策略模式实例策略模式实例策略模式实例策略模式实例
策略模式代码,两种方式实现,第一种,通过map存储方式,第二种,通过配置文件加反射方式
策略模式的简单例子,根据《Head First设计模式》中第一章中的Duck编写
策略模式例子,纯代码,copy后即可运行; 1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。 2、一个系统需要动态地在几种算法中...
策略模式在实际项目中的应用二,该测试demo为普通项目,导入build path一下lib目录下的jar包,然后运行测试类即可在控制台看到测试结果
处理层的设计采用了设计模式中的策略模式、模板方法模式和工厂模式。 Server端和Client端的实现也采用了分层的设计方式,包含自定义的模型层、视图层和控制层。 说明:程序采用配置文件的方式进行初始化,运行时时请...
55-Java设计模式之策略模式与状态模式1
设计模式中的策略模式,同时兼容简单工厂模式,商场收银模式,易懂可用。
策略模式策略模式策略模式
javascript的策略模式和代理模式简介,附代码
在网络上看到几个加密解密算法,本着"取之于民用之于民"的方针测试一下,并用策略模式将这些算法封装共享。
设计模式中的策略模式,template模式详细讲解。