一、优缺点(PPT):
优点:
策略模式可以避免让客户端涉及到不必要接触到的复杂的和只与算法有关的数据。
避免使用难以维护的多重条件选择语句,更好的扩展
缺点:
上述策略模式,把分支判断又放回到客户端,要改变需求算法时,还是要去更改客户端的程序。
客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。
增加了对象的数目。
只适合扁平的算法结构。
二、应用场景:
出现同一个算法,有很多不同的实现的情况,可以使用策略模式来把这些“不同的实现”实现成为一个算法的类层次 。
出现抽象一个定义了很多行为的类,并且是通过多个if-else语句来选择这些行为的情况,可以使用策略模式来代替这些条件语句
三、实例:
1、商场收费系统:(课本)
代码实现:
package 商场收费系统;
public abstract class CashSuper {
public abstract double getResult(double money);
}
package 商场收费系统;
public class CashNormal extends CashSuper{
public double getResult(double money) {
return money;
}
}
package 商场收费系统;
public class CashRebate extends CashSuper{
private double moneyRebate;
public CashRebate() {
}
public CashRebate(double tmp){
moneyRebate=tmp;
}
public double getResult(double money) {
return money*moneyRebate;
}
}
package 商场收费系统;
public class CashReturn extends CashSuper{
private double moneyCondition;
private double moneyReturn;
public CashReturn(double mc,double mr) {
moneyCondition=mc;
moneyReturn=mr;
}
public CashReturn() {
}
public double getResult(double money) {
double res=money-(int)(money/moneyCondition)*moneyReturn;
return res;
}
}
package 商场收费系统;
public class CashContext {
private CashSuper cs;
public CashContext(String type) {
if(type.equals("正常收费")) {
cs=new CashNormal();
}else if(type.equals("满300减100")) {
cs=new CashReturn(300,100);
}
else if(type.equals("打8折")) {
cs=new CashRebate(0.8);
}
}
public double getResult(double money){
return cs.getResult(money);
}
}
package 商场收费系统;
public class Client {
public static void main(String[] args) {
CashContext sup=new CashContext("打8折"/*优惠策略*/);
double totPrice=sup.getResult(100/*处理前总价格*/); //最终价格
}
}
2、日志记录的例子(PPT)
把日志记录到数据库和日志记录到文件当做两种记录日志的策略
UML图:
代码实现:
package 日志文件;
//抽象策略类
public interface LogStrategy {
public void log(String str);
}
//上下文类
package 日志文件;
import java.io.File;
public class LogContext {
private LogStrategy ls;
public void log(String str) {
try {
ls=new DbLog();
ls.log(str);
} catch (Exception e) {
ls=new FileLog();
ls.log(str);
}
}
}
//具体策略类
public class FileLog implements LogStrategy {
public void log(String str) {
System.out.println("正在将“"+str+"”写到日志文件里!");
}
}
package 日志文件;
public class DbLog implements LogStrategy {
public void log(String s) {
int len=s.length();
if(len>5&&s!=null){
int a=5/0;
}
System.out.println("正在将“"+s+"”写到数据库zhong!");
}
}
//场景类
package 日志文件;
public class Client {
public static void main(String[] args) {
LogContext lc=new LogContext();
lc.log("写文件");
lc.log("再来一次写文件吧");
}
}
3、工资支付的例子(PPT)
场景:很多企业的工资支付方式是很灵活的,可支付方式是比较多的,比如:人民币现金支付、美元现金支付、银行转账到工资帐户、银行转账到工资卡;一些创业型的企业为了留住骨干员工,还可能有:工资转股权等等方式
随着公司的发展,会不断有新的工资支付方式出现,这就要求能方便的扩展;另外工资支付方式不是固定的,是由公司和员工协商确定的,也就是说可能不同的员工采用的是不同的支付方式,甚至同一个员工,不同时间采用的支付方式也可能会不同,这就要求能很方便的切换具体的支付方式。
UML图:
代码实现:
package 发工资;
public interface PaymentStrategy {
public void pay(PaymentContext ctx) ;
}
package 发工资;
public class RMBCash implements PaymentStrategy {
public void pay(PaymentContext ctx) {
System.out.println("现在给"+ctx.getName()+"人民币现金支付"+ctx.getMoney()+"元");
}
}
package 发工资;
public class DollarCash implements PaymentStrategy {
public void pay(PaymentContext ctx) {
System.out.println("现在给"+ctx.getName()
+"美元现金支付"+ctx.getMoney()+"元");
}
}
package 发工资;
public class PaymentContext {
private double money;
private String name;
private PaymentStrategy ps;
public PaymentContext(String n,double m,PaymentStrategy p) {
name=n;
money=m;
ps=p;
}
public double getMoney() {
return money;
}
public String getName() {
return name;
}
public PaymentStrategy getPs() {
return ps;
}
public void pay() {
ps.pay(this);
}
}
package 发工资;
public class Client {
public static void main(String[] args) {
PaymentStrategy ps1=new DollarCash();
PaymentStrategy ps2=new RMBCash();
PaymentContext xiaoMing=new PaymentContext("xiaoMing",100,ps1);
PaymentContext xiaoLi=new PaymentContext("xiaoLi",150,ps2);
xiaoMing.pay();
xiaoLi.pay();
}
}
THE END;