设计模式之strategy(策略模式)

来源:互联网 发布:淘宝网怎么解绑手机号 编辑:程序博客网 时间:2024/06/10 09:13

我们经常需要比较两个对象,或者形成一个行为策略,而究竟采用哪一种策略呢?是把策略写死在函数里?如果我们商城打折,那每次都得修改这个函数?或许我们可以把策略抽取程一个类,用面向对象来解决,后文加上了用配置文件来修改这种策略,使得其更加灵活(用到反射)

comparator

如果我们要实现某两个类的比较机制,可以实现comparable接口,实现里面的compareTo()方法,那么我们就可以实现二者比较了

package com.ylf.compare;

 

 

public interfaceComparable{

 public intcompareTo(Objecto);

}

假设我们这里的比较类是Computer

package com.ylf.compare;

 

import javax.swing.text.html.HTMLDocument.HTMLReader.IsindexAction;

 

public classComputerimplements Comparable{

 

 private int price;

 private int ability;

 

 

 publicComputer(intprice,int ability) {

 super();

 this.price=price;

 this.ability=ability;

}

 

 

 public intgetPrice(){

 return price;

}

 

 

 public voidsetPrice(intprice){

 this.price=price;

}

 

 

 public intgetAbility(){

 return ability;

}

 

 

 public voidsetAbility(intability){

 this.ability=ability;

}

 

 

 @Override

 public intcompareTo(Object o){

 if(!(oinstanceof Computer))

  return-2;

 Computerc = (Computer)o;

 if(this.price<c.getPrice())

  return-1;

 else if(this.price==c.getPrice())

  return0;

 else

  return1;

}

 

}

那么我们在Main里面比较很简单,只需要简单调用CompareTo方法就可以了

package com.ylf.compare;

 

public classMain{

 

 public static voidmain(String[]args) {

 Computerc1 = new Computer(4000,90);

 Computerc2 = new Computer(5000,95);

 

 int re=c1.compareTo(c2);

 System.out.println("result:"+re);

}

 

}

但是问题来了,如果我们要比较的不是价格,而是电脑性能了怎么办呢?

很简单,改下compareTo()方法就可以了,但是这样还是很麻烦,如果我们希望在一个配置文件里实现比较策略,那么这样就不行了,从面向对象角度出发,比较的物体是对象,比较这个过程或者说比较这个策略我们是否也可以看成一个对象?

 

假设我们有Comparator这个比较策略,在compareTo()方法里调用这个比较策略来实现返回比较结果,如果我们比较价格,那就创建一个PriceComparator 如果 比较性能,那就创建 AbilityComparator这样虽然在类数目上增加了,但是我们类的灵活度大大提高了。

也就是让我们的电脑实体拥有一个比较器(comarator)这个比较器专门用来比较,至于怎么比较那就是比较器实现问题!这里用组合形式降低了类之间的耦合度

形容的在恰当点,二者要发生关系,如果太死板,没啥花样,每次都一样,容易厌倦,如果把二者发生的这个关系抽象出一个类,那么每次玩啥花样呢?不用想,直接去买一个中介,每次都很不一样啦!

首先添加一个比较器,这里作为抽象类

package com.ylf.compare;

 

public abstract classComparator{

 public abstract intcompare(Objecto1, Object o2);

}

computer类里改变就是添加了一个比较器的持有,同时比较方法采用比较器进行

package com.ylf.compare;

 

import javax.swing.text.html.HTMLDocument.HTMLReader.IsindexAction;

 

public classComputerimplements Comparable{

 

 private int price;

 private int ability;

 privateComparatorcomparator;

 

 publicComputer(intprice,int ability) {

 super();

 this.price=price;

 this.ability=ability;

}

 

 

 public intgetPrice(){

 return price;

}

 

 

 public voidsetPrice(intprice){

 this.price=price;

}

 

 

 public intgetAbility(){

 return ability;

}

 

 

 public voidsetAbility(intability){

 this.ability=ability;

}

 

 publicComparatorgetComparator() {

 return comparator;

}

 

 

 public voidsetComparator(Comparatorcomparator) {

 this.comparator=comparator;

}

 

 

 @Override

 public intcompareTo(Object o){

 //这里把具体比较策略转交给比较器

 return comparator.compare(this,o);

}

 

 

}

假设我们这里实现了性能比较器

package com.ylf.compare;

 

public classAbilityComparatorextends Comparator{

 

 @Override

 public intcompare(Objecto1, Object o2) {

 if(!(o1instanceof Computer) || !(o2instanceof Computer))

  return-2;

 Computerc1 = (Computer)o1;

 Computerc2 = (Computer)o2;

 

 if(c1.getAbility()< c2.getAbility())

  return-1;

 else if(c1.getAbility()== c2.getAbility())

  return0;

 else

  return1;

}

 

}

那么Main里比较就只要借助Computer对象里的比较器进行就可以

package com.ylf.compare;

 

public classMain{

 

 public static voidmain(String[]args) {

 Computerc1 = new Computer(4000,95);

 Computerc2 = new Computer(5000,95);

 

 Comparatorc = new PriceComparator();

 

 c1.setComparator(c);

 

 intre =c1.compareTo(c2);

 System.out.println("result:"+re);

}

 

}

如果我们有一个配置文件,记录了比较器的选择,那么修改他就好了,然后在Main 方法里

package com.ylf.compare;

 

public classMain{

 

 public static voidmain(String[]args) {

 Computerc1 = new Computer(4000,95);

 Computerc2 = new Computer(5000,95);

 

 //Comparatorc = new PriceComparator();

 

 try{

  //假设我们从配置文件读取了配置信息在comparatorStr

  StringcomparatorStr = "com.ylf.compare.PriceComparator";

  //反射生成Class

  ClasscomparatorClass =Class.forName(comparatorStr);

  Comparatorc = (Comparator)comparatorClass.newInstance();

  

  c1.setComparator(c);

  

  intre =c1.compareTo(c2);

  System.out.println("result:"+re);

 }catch(Exceptione){

  e.printStackTrace();

 }

}

 

}

原创粉丝点击