委派模式(Delegate Pattern)
基本作用:负责任务的调度和分配任务,跟代理模式很像,可以看作是一种特殊情况下的静态代理的全权代理,但是代理模式更加注重过程,而委派模式更加注重结果
不属于GOF 23中设计模式之一
属于行为行模型
简单示例:(注册模式+工厂模式+委派模式)
public interface Coder {
public void coding();
}
public class JavaCoder implements Coder {
@Override
public void coding() {
System.out.println("use Java");
}
}
public class PythonCoder implements Coder {
@Override
public void coding() {
System.out.println("use python");
}
}
public class Leader {
private Map<String, Coder> job = new HashMap<>();
public Leader() {
job.put("JAVA", new JavaCoder());
job.put("PYTHON", new PythonCoder());
}
public void doing(String commond) {
commond = commond.toUpperCase();
if (job.containsKey(commond)) {
Coder coder = job.get(commond);
coder.coding();
} else {
System.out.println("沒有该工种的员工");
}
}
}
public class Boss {
public void commond(String commond) {
Leader leader = new Leader();
leader.doing(commond);
}
public static void main(String[] args) {
Boss boss = new Boss();
boss.commond("java");
boss.commond("python");
}
}
执行结果:
use Java
use python
策略模式(Strategy attern)
是指定义算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的用户
可以避免多重分支的if...else....和switch语句
使用场景:
1、假如系统中有很多的类,而他们的区别仅仅在于他们的行为不同
2、一个系统需要动态地在几种算法中选择一种
改造前的简单示例:
public interface PromotionStrategy {
void execute();
}
public class GroupByPromotion implements PromotionStrategy {
@Override
public void execute() {
System.out.println("组团促销活动!");
}
}
public class EmptyPromotion implements PromotionStrategy {
@Override
public void execute() {
System.out.println("没有促销活动!");
}
}
public class CouponPromotion implements PromotionStrategy {
@Override
public void execute() {
System.out.println("优惠券促销活动!");
}
}
public class CashBackPromotion implements PromotionStrategy {
@Override
public void execute() {
System.out.println("返现促销活动!");
}
}
public class PromotionActivity {
private PromotionStrategy promotionStrategy;
public PromotionActivity(PromotionStrategy promotionStrategy) {
this.promotionStrategy = promotionStrategy;
}
public void execute() {
promotionStrategy.execute();
}
}
public class StrategyTest {
public static void main(String[] args){
while (true) {
System.out.println("请输入促销活动:");
Scanner scanner = new Scanner(System.in);
String strategy = scanner.nextLine();
strategy = strategy.toUpperCase();
PromotionStrategy promotionStrategy = null;
if (strategy.equals("COUPON")) {
promotionStrategy = new CouponPromotion();
} else if (strategy.equals("CASHBACK")) {
promotionStrategy = new CashBackPromotion();
} else if (strategy.equals("GROUPBY")) {
promotionStrategy = new GroupByPromotion();
} else {
promotionStrategy = new EmptyPromotion();
}
PromotionActivity promotionActivity = new PromotionActivity(promotionStrategy);
promotionActivity.execute();
System.out.println();
System.out.println("是否退出:Y/N");
String order = scanner.nextLine();
if (order.equals("Y")) {
break;
}
}
}
}
执行结果为:
请输入促销活动:
coupon
优惠券促销活动!
是否退出:Y/N
n
请输入促销活动:
fd
没有促销活动!
是否退出:Y/N
Y
Process finished with exit code 0
结构关系图为:
使用工厂模式,单例模式,注册式模式,添加一个工厂类PromotionStrategyFactory
改造后的代码示例:
public class PromotionStrategyFactory {
private static Map<String, PromotionStrategy> PROMOTION_STRAREGY = new HashMap<>();
static {
PROMOTION_STRAREGY.put(StrategyName.EMPTY.name(), new EmptyPromotion());
PROMOTION_STRAREGY.put(StrategyName.GROUPBY.name(), new GroupByPromotion());
PROMOTION_STRAREGY.put(StrategyName.COUPON.name(), new CouponPromotion());
PROMOTION_STRAREGY.put(StrategyName.CASHBACK.name(), new CashBackPromotion());
}
private PromotionStrategyFactory() {
}
public static PromotionStrategy execute(String strategy) {
strategy = strategy.toUpperCase();
if (PROMOTION_STRAREGY.containsKey(strategy)) {
return PROMOTION_STRAREGY.get(strategy);
} else {
return PROMOTION_STRAREGY.get(StrategyName.EMPTY.name());
}
}
public enum StrategyName {
EMPTY("没有优惠活动"),
GROUPBY("拼团活动"),
COUPON("优惠券活动"),
CASHBACK("返现活动");
public String StrategyName;
StrategyName(String StrategyName) {
this.StrategyName = StrategyName;
}
}
}
public class StrategyTest {
public static void main(String[] args) {
while (true) {
System.out.println("请输入促销活动:");
Scanner scanner = new Scanner(System.in);
String strategy = scanner.nextLine();
PromotionActivity promotionActivity = new PromotionActivity(PromotionStrategyFactory.execute(strategy));
promotionActivity.execute();
System.out.println();
System.out.println("是否退出:Y/N");
String order = scanner.nextLine();
if (order.equals("Y")) {
break;
}
}
}
}
执行结果:
请输入促销活动:
coupon
优惠券促销活动!
是否退出:Y/N
cashback
请输入促销活动:
cashback
返现促销活动!
是否退出:Y/N
n
请输入促销活动:
fdfeidaadfjaisfoa
没有促销活动!
是否退出:Y/N
Y
Process finished with exit code 0
结构关系图如下:
简单支付案例:
public abstract class Payment {
public abstract String getName();
public abstract BigDecimal queryRest();
public abstract void pay(BigDecimal amount);
public MsgResult pay(Long uid, BigDecimal amount) {
BigDecimal bigDecimal = queryRest().subtract(amount);
if (bigDecimal.signum() == -1) {
return new MsgResult(500, "支付失败", "余额不足,余额为:" + queryRest().toString());
}
pay(amount);
return new MsgResult(200, "支付成功", "余额为:" + queryRest());
}
}
public class AliPay extends Payment {
private static BigDecimal rest = new BigDecimal("3000");
@Override
public String getName() {
return "支付宝支付";
}
@Override
public BigDecimal queryRest() {
return rest;
}
@Override
public void pay(BigDecimal amount) {
rest = rest.subtract(amount);
}
}
public class JDPay extends Payment {
private static BigDecimal rest = new BigDecimal("2000");
@Override
public String getName() {
return "京东支付";
}
@Override
public BigDecimal queryRest() {
return rest;
}
@Override
public void pay(BigDecimal amount) {
rest = rest.subtract(amount);
}
}
public class UnionPay extends Payment {
private static BigDecimal rest = new BigDecimal("600");
@Override
public String getName() {
return "银联支付";
}
@Override
public BigDecimal queryRest() {
return rest;
}
@Override
public void pay(BigDecimal amount) {
rest = rest.subtract(amount);
}
}
public class WechatPay extends Payment {
private static BigDecimal rest = new BigDecimal("900");
@Override
public String getName() {
return "微信支付";
}
@Override
public BigDecimal queryRest() {
return rest;
}
@Override
public void pay(BigDecimal amount) {
rest = rest.subtract(amount);
}
}
public class PayStrategyFactory {
private static Map<String, Payment> paymentMap = new HashMap<>();
private PayStrategyFactory() {
}
public static Payment getPayMent(String strategyName) {
strategyName = strategyName.toUpperCase();
if (paymentMap.containsKey(strategyName)) {
return paymentMap.get(strategyName);
}
return paymentMap.get(StrategyName.ALI.name());
}
static {
paymentMap.put(StrategyName.ALI.name(), new AliPay());
paymentMap.put(StrategyName.JD.name(), new JDPay());
paymentMap.put(StrategyName.WECHAT.name(), new WechatPay());
paymentMap.put(StrategyName.UNION.name(), new UnionPay());
}
public enum StrategyName {
ALI("支付宝支付"),
JD("京东支付"),
WECHAT("微信支付"),
UNION("银联支付");
private String strategyName;
StrategyName(String strategyName) {
this.strategyName = strategyName;
}
}
}
public class MsgResult {
private int code;
private String msg;
private Object data;
public MsgResult(int code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}
@Override
public String toString() {
return "MsgResult{" + "code=" + code + ", msg='" + msg + '\'' + ", data=" + data + '}';
}
}
public class Order {
private Long uid;
private String orderId;
private BigDecimal amount;
public Order(BigDecimal amount) {
this.amount = amount;
}
public Order(Long uid, String orderId, BigDecimal amount) {
this.uid = uid;
this.orderId = orderId;
this.amount = amount;
}
public MsgResult pay(String strategy) {
Payment payment = PayStrategyFactory.getPayMent(strategy);
return payment.pay(this.uid, this.amount);
}
@Override
public String toString() {
return "Order{" + "uid=" + uid + ", orderId='" + orderId + '\'' + ", amount=" + amount + '}';
}
}
public class PayStrategyTest {
public static void main(String[] args) {
while (true) {
System.out.println("请输入支付方式:");
Scanner scanner = new Scanner(System.in);
String payWay = scanner.nextLine();
System.out.println("请输入支付金额:");
String amountStr = scanner.nextLine();
Order order = new Order(19L, "", new BigDecimal(amountStr));
MsgResult msgResult = order.pay(payWay);
System.out.println(msgResult.toString());
System.out.println("是否继续:Y/N");
String judge = scanner.nextLine();
if (judge.equals("N")) {
break;
}
}
}
}
执行结果为:
请输入支付方式:
ali
请输入支付金额:
100
MsgResult{code=200, msg='支付成功', data=余额为:2900}
是否继续:Y/N
Y
请输入支付方式:
ali
请输入支付金额:
100
MsgResult{code=200, msg='支付成功', data=余额为:2800}
是否继续:Y/N
Y
请输入支付方式:
wechat
请输入支付金额:
100
MsgResult{code=200, msg='支付成功', data=余额为:800}
是否继续:Y/N
Y
请输入支付方式:
ali
请输入支付金额:
300
MsgResult{code=200, msg='支付成功', data=余额为:2500}
是否继续:Y/N
相关类的结构关系图如下所示:
策略模式的优点:
1、符合开闭原则
2、避免使用多重条件转移语句,如:if...else...语句,switch语句
3、使用策略模式可以提高算法的保密性和安全性。
策略模式的缺点:
1、客户端必须知道所有的策略,并且自行决定使用哪一个策略类
2、代码中会产生非常多的策略,增加了维护难度
实现简单的DispatcherServlet,示例如下:
public class MemberController {
public void getMemberById(String mid){
}
}
public class OrderController {
public void getOrderById(String mid){
}
}
public class SystemController {
public void logout(String mid){
}
}
public class SimpleDispatcherServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doDispatcher(req, resp);
}
private void doDispatcher(HttpServletRequest req, HttpServletResponse resp) {
String uri = req.getRequestURI();
String mid = req.getParameter("mid");
if (uri.equals("getMemberById")) {
new MemberController().getMemberById(mid);
} else if (uri.equals("getOrderById")) {
new OrderController().getOrderById(mid);
} else if (uri.equals("logout")) {
new SystemController().logout(mid);
} else {
try {
resp.getWriter().write("404 not found");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
使用策略模式实现简单的DispatcherServlet,示例如下:
public class SimpleDispatcherServlet extends HttpServlet {
private List<Hander> requestMapping = new ArrayList<>();
@Override
public void init() throws ServletException {
Class<?> clzz = MemberController.class;
try {
requestMapping.add(
new Hander().setController(clzz.newInstance()).setMethod(clzz.getMethod("getMemberById", String.class))
.setUrl("/member/getMemberById"));
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doDispatcher1(req, resp);
}
private void doDispatcher1(HttpServletRequest req, HttpServletResponse resp) {
String uri = req.getRequestURI();
String mid = req.getParameter("mid");
Hander hander = null;
for (Hander handerInner : requestMapping) {
if (handerInner.getUrl().equals(uri)) {
hander = handerInner;
break;
}
}
if (hander==null){
try {
resp.getWriter().write("404 not found");
} catch (IOException e) {
e.printStackTrace();
}
}
try {
Object object = hander.getMethod().invoke(hander.getController(), mid);
resp.getWriter().write(object.toString());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
class Hander {
private Object controller;
private Method method;
private String url;
public Object getController() {
return controller;
}
public Hander setController(Object controller) {
this.controller = controller;
return this;
}
public Method getMethod() {
return method;
}
public Hander setMethod(Method method) {
this.method = method;
return this;
}
public String getUrl() {
return url;
}
public Hander setUrl(String url) {
this.url = url;
return this;
}
}
}