1、策略模式 [ Strategy Pattern ] 又叫政策模式 [ Policy Pattern ],它是将定义得算法家族、分别封装起来,让他们之间可以互相替换,从而让算法得变化不会影响到使用算法的用户
2、可以避免多重分支的 if...else...和 switch 语句
3、属于《行为型模式》
【适用场景】
1、假如系统种有很多类,而他们的区别仅仅在于他们的行为不同
2、一个系统需要动态的再几种算法种选择一种
3、需要屏蔽算法规则
//优惠策略
public interface IPromotionStrategy {
void doPromotion();
}
//优惠券
public class CouponStrategy implements IPromotionStrategy {
public void doPromotion() {
System.out.println("使用优惠券抵扣");
}
}
//返现
public class CashbackStrategy implements IPromotionStrategy {
public void doPromotion() {
System.out.println("返现,直接打款到支付宝账号");
}
}
//拼团
public class GroupbuyStrategy implements IPromotionStrategy {
public void doPromotion() {
System.out.println("5人成团,可以优惠");
}
}
//无优惠
public class EmptyStrategy implements IPromotionStrategy {
public void doPromotion() {
System.out.println("无优惠");
}
}
//调用
public static void main(String[] args) {
String promotion = "";
IPromotionStrategy strategy = null;
if("团购".equals(promotion)){
new PromotionActivity(new GroupbuyStrategy());
}else if("".equals(promotion)){
//很不优雅,怎么办呢?
}else if("".equals(promotion)){
}
strategy.doPromotion();
}
/*
优化
1、加入上下文
2、加入策略工厂
*/
//上下文
public class PromotionActivity {
private IPromotionStrategy strategy;
public PromotionActivity(IPromotionStrategy strategy) {
this.strategy = strategy;
}
public void execute(){
strategy.doPromotion();
}
}
//策略工厂
public class PromotionStrategyFacory {
private static Map<String,IPromotionStrategy> PROMOTIONS = new HashMap<String,IPromotionStrategy>();
static {
PROMOTIONS.put(PromotionKey.COUPON,new CouponStrategy());
PROMOTIONS.put(PromotionKey.CASHBACK,new CashbackStrategy());
PROMOTIONS.put(PromotionKey.GROUPBUY,new GroupbuyStrategy());
}
private static final IPromotionStrategy EMPTY = new EmptyStrategy();
private PromotionStrategyFacory(){}
public static IPromotionStrategy getPromotionStrategy(String promotionKey){
IPromotionStrategy strategy = PROMOTIONS.get(promotionKey);
return strategy == null ? EMPTY : strategy;
}
private interface PromotionKey{
String COUPON = "COUPON";
String CASHBACK = "CASHBACK";
String GROUPBUY = "GROUPBUY";
}
public static Set<String> getPromotionKeys(){
return PROMOTIONS.keySet();
}
}
//调用
public static void main(String[] args) {
//PromotionStrategyFacory.getPromotionKeys();
String promotionKey = "COUPON";
IPromotionStrategy promotionStrategy = PromotionStrategyFacory.getPromotionStrategy(promotionKey);
promotionStrategy.doPromotion();
}
//抽象策略
public abstract class Payment {
public abstract String getName();
//通用逻辑放到抽象类里面实现
public MsgResult pay(String uid, double amount){
//余额是否足够
if(queryBalance(uid) < amount){
return new MsgResult(500,"支付失败","余额不足");
}
return new MsgResult(200,"支付成功","支付金额" + amount);
}
protected abstract double queryBalance(String uid);
}
//支付宝
public class AliPay extends Payment {
public String getName() {
return "支付宝";
}
protected double queryBalance(String uid) {
return 900;
}
}
//微信
public class WechatPay extends Payment {
public String getName() {
return "微信支付";
}
protected double queryBalance(String uid) {
return 263;
}
}
//京东
public class JDPay extends Payment {
public String getName() {
return "京东白条";
}
protected double queryBalance(String uid) {
return 500;
}
}
//银联
public class UnionPay extends Payment {
public String getName() {
return "银联支付";
}
protected double queryBalance(String uid) {
return 120;
}
}
//上下文
public class PayStrategy {
public static final String ALI_PAY = "AliPay";
public static final String JD_PAY = "JdPay";
public static final String WECHAT_PAY = "WechatPay";
public static final String UNION_PAY = "UnionPay";
public static final String DEFAULT_PAY = ALI_PAY;
private static Map<String,Payment> strategy = new HashMap<String,Payment>();
static {
strategy.put(ALI_PAY,new AliPay());
strategy.put(JD_PAY,new JDPay());
strategy.put(WECHAT_PAY,new WechatPay());
strategy.put(UNION_PAY,new UnionPay());
}
public static Payment get(String payKey){
if(!strategy.containsKey(payKey)){
return strategy.get(DEFAULT_PAY);
}
return strategy.get(payKey);
}
}
//消息
public class MsgResult {
private int code;
private Object data;
private String msg;
public MsgResult(int code, String msg, Object data) {
this.code = code;
this.data = data;
this.msg = msg;
}
@Override
public String toString() {
return "MsgResult{" +
"code=" + code +
", data=" + data +
", msg=‘" + msg + ‘\‘‘ +
‘}‘;
}
}
//订单
public class Order {
private String uid;
private String orderId;
private double amount;
public Order(String uid, String orderId, double amount) {
this.uid = uid;
this.orderId = orderId;
this.amount = amount;
}
public MsgResult pay(){
return pay(PayStrategy.DEFAULT_PAY);
}
public MsgResult pay(String payKey){
Payment payment = PayStrategy.get(payKey);
System.out.println("欢迎使用" + payment.getName());
System.out.println("本次交易金额为" + amount + ",开始扣款");
return payment.pay(uid,amount);
}
}
//调用
public class Test {
public static void main(String[] args) {
Order order = new Order("1","2020031401000323",324.5);
System.out.println(order.pay(PayStrategy.UNION_PAY));
}
}
策略模式的优点
1、符合开闭原则
2、避免多重条件转移语句
3、提高算法的保密性和安全性
策略模式的缺点
1、客户端必须知道所有的策略,并且自行决定适用哪一个策略类
2、代码种会产生非常多策略类,增加维护难度
1、责任链模式 [Chain of Responsibility Pattern] 是将链中每一个节点看作是一个对象,每个节点处理的请求均不同,且内部自动维护一个下一节点对象。
2、当一个请求从链式的首端发出时,会沿着链的路径依次传递给每一个节点对象,甚至有对象处理这个请求为止
3、属于《行为型模式》
【适用场景】
1、多个对象可以处理同意请求,但是具体由哪个对象处理则再运行时动态决定
2、在不明确指定接收者的情况下,向多个对象种的一个提交一个请求
3、可动态指定一组对象处理请求
//对象
public class Member {
private String loginName;
private String loginPass;
private String roleName;
public Member(String loginName, String loginPass) {
this.loginName = loginName;
this.loginPass = loginPass;
}
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getLoginPass() {
return loginPass;
}
public void setLoginPass(String loginPass) {
this.loginPass = loginPass;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
@Override
public String toString() {
return "Member{" +
"loginName=‘" + loginName + ‘\‘‘ +
", loginPass=‘" + loginPass + ‘\‘‘ +
", roleName=‘" + roleName + ‘\‘‘ +
‘}‘;
}
}
//抽象处理器
public abstract class Handler {
protected Handler next;//下一个,传播
public void next(Handler next){ this.next = next;}
public abstract void doHandler(Member member);
}
//校验处理器
public class ValidateHandler extends Handler {
public void doHandler(Member member) {
if(StringUtils.isEmpty(member.getLoginName()) ||
StringUtils.isEmpty(member.getLoginPass())){
System.out.println("用户名和密码为空");
return;
}
System.out.println("用户名和密码不为空,可以往下执行");
next.doHandler(member);
}
}
//登录处理器
public class LoginHandler extends Handler {
public void doHandler(Member member) {
System.out.println("登录成功!");
member.setRoleName("管理员");
next.doHandler(member);
}
}
//权限处理器
public class AuthHandler extends Handler {
public void doHandler(Member member) {
if(!"管理员".equals(member.getRoleName())){
System.out.println("您不是管理员,没有操作权限");
return;
}
System.out.println("允许操作");
}
}
//传起来
public class MemberService {
public void login(String loginName,String loginPass){
Handler validateHandler = new ValidateHandler();
Handler loginHandler = new LoginHandler();
Handler authHandler = new AuthHandler();
validateHandler.next(loginHandler);
loginHandler.next(authHandler);
validateHandler.doHandler(new Member(loginName,loginPass));
}
}
//调用
public static void main(String[] args) {
MemberService memberService = new MemberService();
memberService.login("tom","666");
}
1、总是调用next(),next()太多容易混乱
2、加入建造者模式来优化
//抽象处理器
public abstract class Handler<T> {
protected Handler next;
public void next(Handler next){ this.next = next;}
public abstract void doHandler(Member member);
public static class Builder<T>{
private Handler<T> head;
private Handler<T> tail;
public Builder<T> addHandler(Handler handler){
// do {
if (this.head == null) {
this.head = this.tail = handler;
return this;
}
this.tail.next(handler);
this.tail = handler;
// }while (false);//真正框架中,如果是双向链表,会判断是否已经到了尾部
return this;
}
public Handler<T> build(){
return this.head;
}
}
}
//service代码优化
public void login(String loginName,String loginPass){
Handler.Builder builder = new Handler.Builder();
builder.addHandler(new ValidateHandler());
.addHandler(new LoginHandler())
.addHandler(new AuthHandler());
builder.build().doHandler(new Member(loginName,loginPass));
}
责任链模式的优点:
1、将请求与处理解耦
2、请求处理者 [节点对象] 只需关注自己感兴趣的请求进行处理即可,对于不感兴趣的请求,直接转发给下一级节点对象
3、具备链式传递处理请求功能,请求发送这无需知晓链路结构,只需等待请求处理结果
4、链路结构灵活,可以通过改变链路结构动态的新增或删除责任
5、易于扩展薪的请求处理类 [节点],符合开闭原则
责任链模式的缺点:
1、责任链太长或者处理时间过长,会影响整体性能
2、如果节点对象存在循环引用时,会造成死循环,导致系统崩溃
原文:https://www.cnblogs.com/JustDoIt-1221/p/14597948.html