策略模式
引子:
话说马上就要到清明节了,公司也放假了,人流量多了,各种商店的生意也好了,但为了加大节日销售的利润,各种商店纷纷出台了相应的打折策略,对于小点的商店,商品相对较少,处理起来也不大费劲,但对于楼下的国美电器呀,附近的苏宁,这样的大店商品太多,打折信息也比较多,对于打折信息的记录当然就会采用一些现代化的方法予以记录,假设有这么一个系统,他就用于处理此次的打折信息!可是,对于大店的他们经常会遇到打折的信息,并且每次的打折还都不一样,有时候这些需要打折,哪些产品不需要,有时候打着多,有时候少,还有一些满消费多少就立减多少,有时候是满多少就送多少,这样每次操作起来一比较繁琐,于是他们就想,能不能开发出来一些列的规则来,让这个系统对与不同的情况进行自动激活响应的策略规则,比如每到周六周日所有商品就打9折,每到法定节日就打8折,满1000元就送100元的礼品,正在搞活动的商品买二送一等。当然,这需要事先把规则定义好,然后让计算机计算执行,可是事情该开始肯定是做不到十全十美的,我们以后有了新的产品可能就会有新的促销策略,于是乎,就需要这个系统能够随时更改相应的规则并且可以随时加入新的规则,而这样的一个系统就实现了我们的策略模式,系统根据不同的事务采取不同的策略执行,可随时添加新的策略执行……
什么是策略模式 策略模式有什么优点和原则
- 策略模式,又叫算法簇模式,就是定义了不同的算法族,并且之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
- 策略模式把会变化的内容取出并封装起来,以便以后可以轻易地改动或扩充部分,而不影响不需要变化的其他部分;
- 策略模式的好处在于你可以动态的改变对象的行为。
- 设计原则是把一个类中经常改变或者将来可能改变的部分提取出来,作为一个接口(c++中可以用虚类),然后在类中包含这个对象的实例,这样类的实例在运行时就可以随意调用实现了这个接口的类的行为。下面是一个例子。
- 策略模式属于对象行为型模式,主要针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。通常,策略模式适用于当一个应用程序需要实现一种特定的服务或者功能,而且该程序有多种实现方式时使用。
(策略模式静态图)
策略模式中有三个对象:
(1) 环境对象:该类中实现了对抽象策略中定义的接口或者抽象类的引用。
(2) 抽象策略对象:它可由接口或抽象类来实现。
(3) 具体策略对象:它封装了实现同不功能的不同算法。
利用策略模式构建应用程序,可以根据用户配置等内容,选择不同有算法来实现应用程序的功能。具体的选择有环境对象来完成。采用这种方式可以避免由于使用条件语句而带来的代码混乱,提高应用程序的灵活性与条理性。
一个策略模式实例
(上文关于打折的实例是策略模式很好的一个例子,为了更好的理解,我再增加一个JDK已存在的我来模拟的实例:大自然是有很多动物组成的,动物多了就容易产生比较的心理,对于比较JDK提供了一个Coparable的接口,其中含有一个compareTo的方法,任何一个对象只要继承了这个接口就具有了比较的功能,可是对于一个对象来说如何进行比较才算是正确的呢?比如说,对于自然界的猫是计较身高来确定大小的呢还是比较体重的呢?还是别的什么的呢?当然这就需要我们自己来定义比较的策略,于是就产生了比较器Comparator,对于确定的比较方案来说当然这个是不需要的,可是为了我们能更好的扩展,我们以后假如加了一些新的比较策略怎么办?很显然就需要在我们的对象里加入一个抽象的比较器Comparator,我们在外部可以自由定义它的比较器,这样就可以随意的比较了,具体我画了一个UML类图予以演示)
程序代码
package strategy.abstractComparator;
public interface Comparator<T> {
int compare(T object1, T object2) ;
}
package strategy.comparable;
public interface Comparable<T> {
int compareTo(T object) ;
}
package strategy.dataSorter;
import strategy.abstractComparator.Comparator;
import strategy.comparable.Comparable;
public class DataSorter {
public static void print(Object [] objects) {
for(Object object:objects)
System.out.print(object+" ");
System.out.println();
}
public static void sort(Comparable[] objects) {
for(int i=objects.length;i>0;--i)
for(int j=0;j<i-1;j++)
if(objects[j].compareTo(objects[j+1])>0)
swap(objects, j, j+1);
}
public static void swap(Object [] objects,int x,int y) {
Object o=objects[x];
objects[x]=objects[y];
objects[y]=o;
}
}
package strategy.realComparator;
import strategy.abstractComparator.Comparator;
import strategy.realObject.Cat;
public class CatHeightComparator implements Comparator<Cat> {
@Override
public int compare(Cat object1, Cat object2) {
if (object1.getHeight()==object2.getHeight())
return 0;
else if(object1.getHeight()>object2.getHeight())
return 1;
else
return -1;
}
}
package strategy.realComparator;
import strategy.abstractComparator.Comparator;
import strategy.realObject.Cat;
public class CatWeightComparator implements Comparator<Cat> {
@Override
public int compare(Cat object1, Cat object2) {
if(object1.getWeight()==object2.getWeight())
return 0;
else if(object1.getWeight()>object2.getWeight())
return 1;
else
return 0;
}
}
package strategy.realComparator;
import strategy.abstractComparator.Comparator;
import strategy.realObject.Dog;
public class DogHeightComparator implements Comparator<Dog> {
@Override
public int compare(Dog object1, Dog object2) {
if (object1.getHeight()==object2.getHeight())
return 0;
else if(object1.getHeight()>object2.getHeight())
return 1;
else
return -1;
}
}
package strategy.realComparator;
import strategy.abstractComparator.Comparator;
import strategy.realObject.Dog;
public class DogWeightComparator implements Comparator<Dog> {
@Override
public int compare(Dog object1, Dog object2) {
if(object1.getWeight()==object2.getWeight())
return 0;
else if(object1.getWeight()>object2.getWeight())
return 1;
else
return 0;
}
}
package strategy.realObject;
import strategy.abstractComparator.Comparator;
import strategy.comparable.Comparable;
public class Cat implements Comparable<Cat> {
private int height;
private int weight;
private Comparator<Cat> catComparator;
@Override
public int compareTo(Cat object) {
return catComparator.compare(this, object);
}
public Cat(int height, int weight, Comparator<Cat> catComparator) {
super();
this.height = height;
this.weight = weight;
this.catComparator = catComparator;
}
public Cat(int height, int weight) {
super();
this.height = height;
this.weight = weight;
}
public Cat() {
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public Comparator<Cat> getCatComparator() {
return catComparator;
}
public void setCatComparator(Comparator<Cat> catComparator) {
this.catComparator = catComparator;
}
@Override
public String toString() {
return height+"|"+weight;
}
}
package strategy.realObject;
import strategy.abstractComparator.Comparator;
import strategy.comparable.Comparable;
public class Dog implements Comparable<Dog> {
private int height;
private int weight;
private Comparator<Dog> dogComparator;
@Override
public int compareTo(Dog dog) {
return dogComparator.compare(this, dog);
}
public Dog(int height, int weight, Comparator<Dog> dogComparator) {
this.height = height;
this.weight = weight;
this.dogComparator = dogComparator;
}
public Dog(int height, int weight) {
this.height = height;
this.weight = weight;
}
public Dog() {
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public Comparator<Dog> getDogComparator() {
return dogComparator;
}
public void setDogComparator(Comparator<Dog> dogComparator) {
this.dogComparator = dogComparator;
}
@Override
public String toString() {
return height+"|"+weight;
}
}
package strategy.test;
import java.util.Arrays;
import strategy.dataSorter.DataSorter;
import strategy.realComparator.CatHeightComparator;
import strategy.realComparator.CatWeightComparator;
import strategy.realComparator.DogWeightComparator;
import strategy.realObject.Cat;
import strategy.realObject.Dog;
public class Test {
public static void buildDogsWithComparator(Dog [] dogs){
for(int i=0;i<dogs.length;++i)
dogs[i].setDogComparator(new DogWeightComparator());
}
public static void buildCatsWithComparator(Cat [] cats){
for(int i=0;i<cats.length;++i)
cats[i].setCatComparator(new CatHeightComparator());
}
public static void main(String[] args) {
Cat cats[]={new Cat(1,2),new Cat(5, 1),new Cat(3,11),new Cat(2,4)};
// Cat cats[]={new Cat(1,2,new CatWeightComparator()),new Cat(5, 1,new CatWeightComparator()),new Cat(3,11,new CatWeightComparator()),new Cat(2,4,new CatWeightComparator())};
DataSorter.print(cats);
DataSorter.sort(cats);
// Arrays.sort(cats);
DataSorter.print(cats);
//==================================
Dog dogs[]={new Dog(1,2),new Dog(5, 1),new Dog(3,11),new Dog(2,4)};
DataSorter.print(dogs);
DataSorter.sort(dogs);
DataSorter.print(dogs);
}
}s