package com.jason.pattern.strategy;
/**
* 策略模式:定义一组算法,将每个算法都封装起来且使它们之间可以互换,使用这种算法在客户端调用
* 它的时候可以互不影响。
* 意义:是开发者可开发出许多可替换部分组成的软件,它们之间弱连接,提高重用性。
* 组成:
* 1-抽象的策略角色~通常由抽象类或接口实现
* 2-具体策略角色~封装了相关的算法和行为
* 3-环境角色~持有一个策略类的引用,最终给客户端调用
* 优点:
* 1-策略模式的用意是针对一组算法,将每一个算法都封装到具有共同接口的独立的类中,从而使得他们
* 之间可以互换。
* 2-策略模式使得算法可以在不影响客户端的情况下发生变化,使得策略模式可以把行为和环境分开
* 缺点:
* 1-客户端必须知道所有的策略类,自行决定使用哪一个策略类,造成策略类过多,解决方案~工厂方法
*
*
* 编写步骤:
* 1-对策略对象编写一个公共的借口;
* 2-编写策略类实现策略的公共借口;
* 3-在使用策略对象的类中保存一个对策略对象的引用(使用set、构造方法注入)。
*
* AbstractStrategy.java -公共的策略借口,有一个计算方法,用于各种计算
* @author Administrator
*
*/
public interface AbstractStrategy
{
int calculate(int a, int b);
}
package com.jason.pattern.strategy;
/**
* 具体的策略类,实现了策略接口的方法,完成加法功能
*
* @author Administrator
*
*/
public class AddStrategy implements AbstractStrategy
{
@Override
public int calculate(int a, int b)
{
return a + b;
}
}
package com.jason.pattern.strategy;
/**
* 减法策略类
*
* @author Jason Liu.
*
*/
public class SubStrategy implements AbstractStrategy
{
@Override
public int calculate(int a, int b)
{
return a - b;
}
}
package com.jason.pattern.strategy;
/**
* 策略的环境角色,持有一个策略类的引用, 完成策略类的实际运算
*
* @author Administrator
*
*/
public class Environment
{
private AbstractStrategy strategy;
public Environment(AbstractStrategy strategy)
{
this.strategy = strategy;
}
/**
* @return the strategy
*/
public AbstractStrategy getStrategy()
{
return strategy;
}
/**
* @param strategy
* the strategy to set
*/
public void setStrategy(AbstractStrategy strategy)
{
this.strategy = strategy;
}
/**
* 完成策略类的实际运算
* @param a
* @param b
* @return
*/
public int calculate(int a, int b)
{
return this.strategy.calculate(a, b);
}
}
package com.jason.pattern.strategy;
/**
* 客户端使用策略类的测试
* @author Administrator
*
*/
public class TestStrategy
{
public static void main(String[] args)
{
AddStrategy add = new AddStrategy();// 加法策略
Environment e = new Environment(add);// 传递策略给环境角色,完成具体运算
System.out.println(e.calculate(3, 4));
e.setStrategy(new SubStrategy());// 减法策略
System.out.println(e.calculate(3, 4));
}
}
//=================================
/下面再写个demo
package com.jason.pattern.strategy.test;
import java.util.List;
/**
* <p>
* 策略类接口,对Person列表进行排序<tt>按姓名、年龄、编号排序(包含正序和倒序)
* </p>
* <p>
* 分为正序和倒序,若姓名或年龄相同,按编号的自然顺序排序
* </p>
*
* @author Administrator
*
*/
public interface ISortStrategy
{
/**
* 定义排序接口,对List<Person>列表排序
*
* @param perList
* @return
*/
public void sort(List<Person> perList);
}
///
package com.jason.pattern.strategy.test;
import java.util.Collections;
import java.util.List;
/**
* <p>
* 具体的策略类,实现排序功能 按姓名、年龄、编号排序
* </p>
* 分为正序和倒序,若姓名或年龄相同,按编号的顺序排序)
*
* @author Administrator
*
*/
public class ConcreteSortStrategy implements ISortStrategy
{
/**
* 排序标记,true为正序,false为倒序
*/
private boolean sortFlag;
/**
* 不同的排序名称@see UtilComparator
*/
private String sortName;
public ConcreteSortStrategy()
{
}
public ConcreteSortStrategy(boolean sortFlag, String sortName)
{
this.sortFlag = sortFlag;
this.sortName = sortName;
}
/**
* @return the sortName
*/
public String getSortName()
{
return sortName;
}
/**
* @param sortName
* the sortName to set
*/
public void setSortName(String sortName)
{
this.sortName = sortName;
}
/**
* @return the sortFlag
*/
public boolean isSortFlag()
{
return sortFlag;
}
/**
* @param sortFlag
* the sortFlag to set
*/
public void setSortFlag(boolean sortFlag)
{
this.sortFlag = sortFlag;
}
/**
* 实现排序接口
*/
@Override
public void sort(List<Person> perList)
{
Collections.sort(
perList,
UtilComparator.getInstance().getComparator(getSortName(),
isSortFlag()));
}
}
package com.jason.pattern.strategy.test;
import java.util.List;
/**
* 策略的环境角色,持有一个策略类的引用, 完成策略类的实际功能
*
* @author Administrator
*
*/
public class Environment implements ISortStrategy
{
private ISortStrategy strategy;
public Environment(ISortStrategy strategy)
{
this.strategy = strategy;
}
/**
* @return the strategy
*/
public ISortStrategy getStrategy()
{
return strategy;
}
/**
* @param strategy
* the strategy to set
*/
public void setStrategy(ISortStrategy strategy)
{
this.strategy = strategy;
}
@Override
public void sort(List<Person> perList)
{
this.strategy.sort(perList);
}
}
/
package com.jason.pattern.strategy.test;
import java.util.Comparator;
/**
* 获取排序接口的工具类,用于获取不同排序接口
*
* @author Administrator
*
*/
public class UtilComparator
{
private static UtilComparator instance = null;
private UtilComparator()
{
}
public static synchronized UtilComparator getInstance()
{
if (instance == null)
return new UtilComparator();
return instance;
}
/**
* 获取相应的排序接口
*
* @param param
* 参数标记不同的排序接口
* @param sortFlag
* 参数标记排序格式,正序为true,倒序为false
* @return
*/
public Comparator<Person> getComparator(String param, boolean sortFlag)
{
if (Constants.C_NAME.equals(param))
return new ComparatorByName(sortFlag);
else if (Constants.C_ID.equals(param))
return new ComparatorById(sortFlag);
else if (Constants.C_AGE.equals(param))
return new ComparatorByAge(sortFlag);
return null;
}
}
///
package com.jason.pattern.strategy.test;
/**
* 人类,用于测试策略类,按姓名、年龄、编号排序; 分为正序和倒序,若姓名或年龄相同,按编号的顺序排序(正序由小到大,倒序则相反)
*
* @author Administrator
*
*/
public class Person
{
private int id;
private String name;
private int age;
public Person(int id, String name, int age)
{
this.id = id;
this.name = name;
this.age = age;
}
/**
* @return the id
*/
public int getId()
{
return id;
}
/**
* @param id
* the id to set
*/
public void setId(int id)
{
this.id = id;
}
/**
* @return the name
*/
public String getName()
{
return name;
}
/**
* @param name
* the name to set
*/
public void setName(String name)
{
this.name = name;
}
/**
* @return the age
*/
public int getAge()
{
return age;
}
/**
* @param age
* the age to set
*/
public void setAge(int age)
{
this.age = age;
}
@Override
public String toString()
{
return this.id + "\t" + this.name + "\t" + this.age;
}
}
package com.jason.pattern.strategy.test;
/**
* 常量工具类
*
* @author Administrator
*
*/
public class Constants
{
public static final String C_NAME = "name";
public static final String C_ID = "id";
public static final String C_AGE = "age";
}