java设计模式之策略模式
来源:互联网 发布:注册淘宝用什么名字好 编辑:程序博客网 时间:2024/05/20 05:08
定义
策略模式就是定义一个算法族,分别封装起来,让他们之前可以互相替换。此模式让算法的变化独立于使用算法的客户。
我的个人理解
定义中的解释可能有些官方,用大白话说,就是为了解决一个问题,定义一组方法类,然后呢,具体要用哪一种方法解决问题,让用户自己去决定。举个现实中的例子,我们去超市买东西,我们就是客户,我们买好东西要付钱了,我们会有很多种方式:支付宝支付,现金支付,微信支付等。具体用哪一种方式来付钱,完全取决于我们自身(客户)。策略模式实际上关心的不是算法的实现,而且提供一种方式管理这些算法。下面以这个购物付款的例子进行编码实现一个简单的策略模式。
编码实现
首先,抽象出一个付款的接口。在设计模式中,很重要的一个设计原则就是面向接口编程(这里的面向接口,是广义的,即面向超类进行编程,也就是说也包含抽象类)。这个付款的接口就是我们客户要使用的付款对象的超类。
public interface PayMethod { void pay();}
其次,定义出我们付款的三种类型,都是该接口的实现类:
public class WechatPay implements PayMethod { @Override public void pay() { System.out.println("我使用微信支付"); }}
public class CashPay implements PayMethod { @Override public void pay() { System.out.println("我使用现金支付"); }}
public class AliPay implements PayMethod { @Override public void pay() { System.out.println("我使用支付宝来支付"); }}现在我们可以定义客户对象了,就是要使用付款方式的对象。我们将付款方式作为客户对象的一个属性,并且以构造方法的形式初始化。
public class Customer { private PayMethod payMethod; public Customer(PayMethod payMethod) { this.payMethod = payMethod; } public void buyGoods() { this.payMethod.pay(); System.out.println("我东西买好了"); }}从代码中我们可以看出,购物的方法buyGoods()实际上是用传入的PayMethod的付款方式进行付款的,由于三种付款方式都实现了付款的接口,也就是都有一个付款的方法。所以这里利用了多态的优势。
现在可以写测试类来测试了,也很简单:
public class Main { public static void main(String[] args) { PayMethod payMethod = new WechatPay(); Customer customer = new Customer(payMethod); customer.buyGoods(); }}我们可以看到,先定义了一个微信的付款方式,再传进实例化的客户对象中,接着我们调用购买buyGoods()方法的时候,实际上用的就是微信的付款方式。至此,一个策略模式的demo已经实现了。
思考策略模式的优缺点
优点:我们从上例中可以看出,策略模式的一个优点,就是将算法统一的管理起来了。这些算法之间相互平等,并且都实现一个接口,包含相同的方法。这使得客户使用的时候可以随意的根据自己的需要切换。
缺点:客户如果想要随意的切换策略,就要知道所有的策略类,不然无法根据自己的需要来确定最终的策略;其次,所有的策略类都是以类的形式存在的,所以如果某一个模式包含的策略比较多时候,会造成类的数量很多,不利于维护。
jdk中用到的策略模式举例
jdk中的比较器的实现,用的实际上就是策略模式,我们在针对一个集合排序的时候,可以传入一个比较器Comparator进行自定义的比较策略实现。如下例:
定义一个Student学生类(重写toString是为了方便打印结果观看):
public class Student { private String name; private Integer age; private String info; public Student() { } public Student(String name, Integer age, String info) { this.name = name; this.age = age; this.info = info; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", info='" + info + '\'' + '}'; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getInfo() { return info; } public void setInfo(String info) { this.info = info; }}先定义一个年龄比较器,根据学生的年龄进行升序排列:
public class AgeComparator implements Comparator<Student> { @Override public int compare(Student o1, Student o2) { return o1.getAge()-o2.getAge(); }}再定义一个姓名比较器,根据学生的姓名进行排序:
public class NameComparator implements Comparator<Student> { @Override public int compare(Student o1, Student o2) { return o1.getName().compareTo(o2.getName()); }}接着编写测试类测试,打印出根据年龄排序和根据姓名排序的集合的值:
public class TestStrategy { public static void main(String[] args) { List<Student> studentList = new ArrayList<Student>(); studentList.add(new Student("zhangsan", 12, "张三")); studentList.add(new Student("lisi", 11, "李四")); studentList.add(new Student("wangwu", 13, "王五")); studentList.add(new Student("zhaoliu", 14, "赵六")); studentList.add(new Student("tianqi", 15, "田七")); Collections.sort(studentList, new AgeComparator()); System.out.println("根据年龄比较==>" + studentList.toString()); Collections.sort(studentList, new NameComparator()); System.out.println("根据姓名比较==>" + studentList.toString()); }}打印结果:
我们可以看到,根据年龄比较的结果,集合按照年龄的大小进行了升序排列;根据姓名比较的结果,集合按照姓名的首字母的码表顺序进行了排序。
上例中的两个比较器,都实现了Comparator的接口,都实现了compare的方法。跟之前的购物付款的例子很相似。
- Java设计模式之策略设计模式
- Java设计模式之策略设计模式
- Java设计模式之策略
- Java设计模式之策略模式
- java设计模式之 策略模式
- JAVA 设计模式之 策略模式
- java设计模式之策略模式 Strategy
- java设计模式之策略模式
- java设计模式之策略模式
- 浅谈Java设计模式之---策略模式
- java设计模式之策略模式
- Java设计模式之策略模式
- java设计模式之策略模式
- Java设计模式之策略模式
- Java设计模式之策略模式
- java设计模式之策略模式
- 设计模式之策略模式(java)
- Java设计模式笔记之策略模式
- 和学生们的合影-20170910-wangdongs-chenqingy-zhaoq-chenxingy-xuyn
- python股票信息爬虫简例
- centOS服务器 netstat命令 查看TCP连接数信息(转)
- android ANR源码分析 --- 之四
- stm32的UART串口通信
- java设计模式之策略模式
- Python连接mysql
- 使用CSS计数器给HTML项目前加序号
- Java校招面试-操作系统
- SSM框架部分搭建流程
- 如何全自动安装虚拟机,kickstart
- 莫要唱《离歌》
- QPainter实现3d柱状图
- 增1减1运算符使用