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

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

comparator

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

package com.ylf.compare;

 

 

public interface Comparable {

 public int compareTo(Object o);

}

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

package com.ylf.compare;

 

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

 

public class Computer implements Comparable{

 

 private int price;

 private int ability;

 

 

 public Computer(int price, int ability) {

 super();

 this.price = price;

 this.ability = ability;

}

 

 

 public int getPrice() {

 return price;

}

 

 

 public void setPrice(int price) {

 this.price = price;

}

 

 

 public int getAbility() {

 return ability;

}

 

 

 public void setAbility(int ability) {

 this.ability = ability;

}

 

 

 @Override

 public int compareTo(Object o) {

 if(!(o instanceof Computer))

  return -2;

 Computer c = (Computer)o;

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

  return -1;

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

  return 0;

 else

  return 1;

}

 

}

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

package com.ylf.compare;

 

public class Main {

 

 public static void main(String[] args) {

 Computer c1 = new Computer(4000, 90);

 Computer c2 = 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  class Comparator {

 public abstract int compare(Object o1, Object o2);

}

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

package com.ylf.compare;

 

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

 

public class Computer implements Comparable{

 

 private int price;

 private int ability;

 private Comparator comparator;

 

 public Computer(int price, int ability) {

 super();

 this.price = price;

 this.ability = ability;

}

 

 

 public int getPrice() {

 return price;

}

 

 

 public void setPrice(int price) {

 this.price = price;

}

 

 

 public int getAbility() {

 return ability;

}

 

 

 public void setAbility(int ability) {

 this.ability = ability;

}

 

 public Comparator getComparator() {

 return comparator;

}

 

 

 public void setComparator(Comparator comparator) {

 this.comparator = comparator;

}

 

 

 @Override

 public int compareTo(Object o) {

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

 return comparator.compare(this, o);

}

 

 

}

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

package com.ylf.compare;

 

public class AbilityComparator extends Comparator{

 

 @Override

 public int compare(Object o1, Object o2) {

 if(!(o1 instanceof Computer) || !(o2 instanceof Computer))

  return -2;

 Computer c1 = (Computer)o1;

 Computer c2 = (Computer)o2;

 

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

  return -1;

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

  return 0;

 else

  return 1;

}

 

}

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

package com.ylf.compare;

 

public class Main {

 

 public static void main(String[] args) {

 Computer c1 = new Computer(4000, 95);

 Computer c2 = new Computer(5000, 95);

 

 Comparator c = new PriceComparator();

 

 c1.setComparator(c);

 

 int re = c1.compareTo(c2);

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

}

 

}

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

package com.ylf.compare;

 

public class Main {

 

 public static void main(String[] args) {

 Computer c1 = new Computer(4000, 95);

 Computer c2 = new Computer(5000, 95);

 

 //Comparator c = new PriceComparator();

 

 try{

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

  String comparatorStr = "com.ylf.compare.PriceComparator";

  //反射生成Class

  Class comparatorClass = Class.forName(comparatorStr);

  Comparator c = (Comparator)comparatorClass.newInstance();

  

  c1.setComparator(c);

  

  int re = c1.compareTo(c2);

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

 }catch(Exception e){

  e.printStackTrace();

 }

}

 

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值