Strategy策略模式

   策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立类中,从而使得它们可以互相替换.策略模式使得算法可以在不影响到客户端的情况下发生变化.
   这个模式涉及三个角色:
*环境(Context)角色:持有一个Strategy类的引用.
*抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现.此角色给出所以的具体策略类所需的接口.
*具体策略(ConcreteStrategy)角色:包装了相关的算法或行为.
1.比较策略:
  环境角色:

public class Cat implements Comparable
{
    private int age;
    private int height;

    //持有一个Strategy类的引用
    private Comparator comparator = new CatHeightComparator();
    //private Comparator comparator = new CatAgeComparator();

    public Comparator getComparator()
    {
        return comparator;
    }
    public void setComparator(Comparator comparator)
    {
        this.comparator = comparator;
    }
    public int getAge()
    {
        return age;
    }
    public void setAge(int age)
    {
        this.age = age;
    }
    public int getHeight()
    {
        return height;
    }
    public void setHeight(int height)
    {
        this.height = height;
    }
    public Cat(int age, int height)
    {
        super();
        this.age = age;
        this.height = height;
    }
    
    @Override
    public String toString()
    {
        return age + "|" + height;
    }
    
    @Override
    public int compareTo(Object o)
    {
        return comparator.compare(this, o);
    }
}


抽象策略(Strategy)角色

public interface Comparator
{
    int compare(Object o1,Object o2);
}


具体策略(ConcreteStrategy)角色1

public class CatAgeComparator implements Comparator
{
    @Override
    public int compare(Object o1, Object o2)
    {
        Cat c1 = (Cat)o1;
        Cat c2 = (Cat)o2;
        if (c1.getAge() > c2.getAge())
        {
            return 1;
        }
        else if (c1.getAge() < c2.getAge())
        {
            return -1;
        }
        return 0;
    }
}


具体策略(ConcreteStrategy)角色2

public class CatHeightComparator implements Comparator
{
    @Override
    public int compare(Object o1, Object o2)
    {
        Cat c1 = (Cat)o1;
        Cat c2 = (Cat)o2;
        if (c1.getHeight() > c2.getHeight())
        {
            return 1;
        }
        else if (c1.getHeight() < c2.getHeight())
        {
            return -1;
        }
        return 0;
    }
}


在排序算法中的使用:

public class DataSorter
{
    public static void sort(Object[] a)
    {
        for (int i = a.length; i > 0; i--)
        {
            for (int j = 0; j < i - 1; j++)
            {
                if (((Comparable)a[j]).compareTo((Comparable)a[j + 1]) == 1)
                {
                    swap(a, j, j + 1);
                }
            }
        }
    }

    private static void swap(Object[] a, int x, int y)
    {
        Object temp = a[x];
        a[x] = a[y];
        a[y] = temp;
    }

    public static void p(Object[] a)
    {
        for (int i = 0; i < a.length; i++)
        {
            System.out.print(a[i] + " ");
        }
        System.out.println();
    }


}

Test:

public static void main(String[] args)

{
    Cat a[] = {new Cat(4,5), new Cat(5,3), new Cat(2,3)};
    DataSorter.sort(a);
    DataSorter.p(a);
}


2.图书打折:

public abstract class DiscountStrategy
{
    private double singlePrice = 0;
    private int copies = 0;
    public DiscountStrategy(double singlePrice, int copies)
    {
        this.singlePrice = singlePrice;
        this.copies = copies;
    }

    public abstract double calculateDiscount();
}


策略1:对有些图书没有折扣

public class NoDiscountStrategy extends DiscountStrategy
{
    private double singlePrice = 0;
    private int copies = 0;
    public NoDiscountStrategy(double singlePrice, int copies)
    {
        super(singlePrice, copies);
    }

    @Override
    public double calculateDiscount()
    {
        return 0;
    }

}


策略2:对有些图书提供一个固定量值的折扣

public class FlatRateStrategy extends DiscountStrategy
{
    private double singlePrice = 0;
    private int copies = 0;
    private Double amount;
    public FlatRateStrategy(double singlePrice, int copies)
    {
        super(singlePrice, copies);
    }

    public Double getAmount()
    {
        return amount;
    }

    public void setAmount(Double amount)
    {
        this.amount = amount;
    }

    @Override
    public double calculateDiscount()
    {
        return copies * amount;
    }

}


策略3:对有些图书提供一个百分比的折扣

public class PercentageStrategy extends DiscountStrategy
{
    private double singlePrice = 0;
    private int copies = 0;
    private Double percent;
    public PercentageStrategy(double singlePrice, int copies)
    {
        super(singlePrice, copies);
    }

    public Double getPercent()
    {
        return percent;
    }

    public void setPercent(Double percent)
    {
        this.percent = percent;
    }

    @Override
    public double calculateDiscount()
    {
        return copies * singlePrice * percent;
    }

}


作者: mingwjj   发布时间: 2010-11-05