demo1
代码片段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class RewardService { private WaimaiService waimaiService; private HotelService hotelService; private FoodService foodService; public void issueReward(String rewardType, Object ... params) { if (“Waimai”.equals(rewardType)) { WaimaiRequest request = new WaimaiRequest(); request.setWaimaiReq(params); waimaiService.issueWaimai(request); } else if (“Hotel”.equals(rewardType)) { HotelRequest request = new HotelRequest(); request.addHotelReq(params); hotelService.sendPrize(request); } else if (“Food”.equals(rewardType)) { FoodRequest request = new FoodRequest(params); foodService.getCoupon(request); } else { throw new IllegalArgumentException(“rewardType error!”); } } }
|
这样设计,如果说需要新添加一个服务,就需要添加如下代码:
1 2 3 4 5
| private NewService newService;
else if ("new".equals(rewardType)) { ... }
|
经过第一次修改后,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| interface Strategy { void issue(Object ... params); }
class Waimai implements Strategy { private WaimaiService waimaiService; @Override public void issue(Object... params) { WaimaiRequest request = new WaimaiRequest(); request.setWaimaiReq(params); waimaiService.issueWaimai(request); } }
class Hotel implements Strategy { private HotelService hotelService; @Override public void issue(Object... params) { HotelRequest request = new HotelRequest(); request.addHotelReq(params); hotelService.sendPrize(request); } }
class Food implements Strategy { private FoodService foodService; @Override public void issue(Object... params) { FoodRequest request = new FoodRequest(params); foodService.payCoupon(request); } }
class StrategyContext { public static Strategy getStrategy(String rewardType) { switch (rewardType) { case“Waimai”: return new Waimai(); case“Hotel”: return new Hotel(); case“Food”: return new Food(); default: throw new IllegalArgumentException(“rewardType error!”); } } }
class RewardService { public void issueReward(String rewardType, Object ... params) { Strategy strategy = StrategyContext.getStrategy(rewardType); strategy.issue(params); } }
|
这种优化,使用了一个接口,没当需要新添加服务时,只需要实现该接口
这次优化后,还有一个问题,那就是策略类,可以改为单例模式,如果之前有,就不需要新创建,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| class StrategyContext { private static final Map<String, Strategy> registerMap = new HashMap<>(); public static void registerStrategy(String rewardType, Strategy strategy) { registerMap.putIfAbsent(rewardType, strategy); } public static Strategy getStrategy(String rewardType) { return registerMap.get(rewardType); } }
abstract class AbstractStrategy implements Strategy { public void register() { StrategyContext.registerStrategy(getClass().getSimpleName(), this); } }
class Waimai extends AbstractStrategy implements Strategy { private static final Waimai instance = new Waimai(); private WaimaiService waimaiService; private Waimai() { register(); } public static Waimai getInstance() { return instance; } @Override public void issue(Object... params) { WaimaiRequest request = new WaimaiRequest(); request.setWaimaiReq(params); waimaiService.issueWaimai(request); } }
class Hotel extends AbstractStrategy implements Strategy { private static final Hotel instance = new Hotel(); private HotelService hotelService; private Hotel() { register(); } public static Hotel getInstance() { return instance; } @Override public void issue(Object... params) { HotelRequest request = new HotelRequest(); request.addHotelReq(params); hotelService.sendPrize(request); } }
class Food extends AbstractStrategy implements Strategy { private static final Food instance = new Food(); private FoodService foodService; private Food() { register(); } public static Food getInstance() { return instance; } @Override public void issue(Object... params) { FoodRequest request = new FoodRequest(params); foodService.payCoupon(request); } }
|
这次优化后,每次注册完成后,map中会有一个该对象,下次使用时就不需要创建,直接拿之前已经有的即可。
demo2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| @AllArgsConstructor @Getter enum TaskState { INIT(“初始化”), ONGOING( “进行中”), PAUSED(“暂停中”), FINISHED(“已完成”), EXPIRED(“已过期”); private final String message; }
@AllArgsConstructor @Getter enum ActionType { START(1, “开始”), STOP(2, “暂停”), ACHIEVE(3, “完成”), EXPIRE(4, “过期”); private final int code; private final String message; }
class Task { private Long taskId; private TaskState state = TaskState.INIT; private ActivityService activityService; private TaskManager taskManager; public void updateState(ActionType actionType) { if (state == TaskState.INIT) { if (actionType == ActionType.START) { state = TaskState.ONGOING; } } else if (state == TaskState.ONGOING) { if (actionType == ActionType.ACHIEVE) { state = TaskState.FINISHED; activityService.notifyFinished(taskId); taskManager.release(taskId); } else if (actionType == ActionType.STOP) { state = TaskState.PAUSED; } else if (actionType == ActionType.EXPIRE) { state = TaskState.EXPIRED; } } else if (state == TaskState.PAUSED) { if (actionType == ActionType.START) { state = TaskState.ONGOING; } else if (actionType == ActionType.EXPIRE) { state = TaskState.EXPIRED; } } } }
|
这里的问题是if-else判断太多,如果新添加状态还需要添加新的if-else,这里可以用状态模式。而且Task类中冗余了TaskManager类。
修改后代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| interface State { default void update(Task task, ActionType actionType) { } }
class TaskInit implements State { @Override public void update(Task task, ActionType actionType) { if (actionType == ActionType.START) { task.setState(new TaskOngoing()); } } }
class TaskOngoing implements State { private ActivityService activityService; private TaskManager taskManager; @Override public void update(Task task, ActionType actionType) { if (actionType == ActionType.ACHIEVE) { task.setState(new TaskFinished()); activityService.notifyFinished(taskId); taskManager.release(taskId); } else if (actionType == ActionType.STOP) { task.setState(new TaskPaused()); } else if (actionType == ActionType.EXPIRE) { task.setState(new TaskExpired()); } } }
class TaskPaused implements State { @Override public void update(Task task, ActionType actionType) { if (actionType == ActionType.START) { task.setState(new TaskOngoing()); } else if (actionType == ActionType.EXPIRE) { task.setState(new TaskExpired()); } } }
class TaskFinished implements State { }
class TaskExpired implements State { } @Data class Task { private Long taskId; private State state = new TaskInit(); public void updateState(ActionType actionType) { state.update(this, actionType); } }
|
采用观察者模式后,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| interface Observer { void response(Long taskId); }
abstract class Subject { protected List<Observer> observers = new ArrayList<Observer>(); public void add(Observer observer) { observers.add(observer); } public void remove(Observer observer) { observers.remove(observer); } public void notifyObserver(Long taskId) { for (Observer observer : observers) { observer.response(taskId); } } }
class ActivityObserver implements Observer { private ActivityService activityService; @Override public void response(Long taskId) { activityService.notifyFinished(taskId); } }
class TaskManageObserver implements Observer { private TaskManager taskManager; @Override public void response(Long taskId) { taskManager.release(taskId); } }
class TaskOngoing extends Subject implements State { @Override public void update(Task task, ActionType actionType) { if (actionType == ActionType.ACHIEVE) { task.setState(new TaskFinished()); notifyObserver(task.getTaskId()); } else if (actionType == ActionType.STOP) { task.setState(new TaskPaused()); } else if (actionType == ActionType.EXPIRE) { task.setState(new TaskExpired()); } } }
class TaskInit implements State { @Override public void update(Task task, ActionType actionType) { if (actionType == ActionType.START) { TaskOngoing taskOngoing = new TaskOngoing(); taskOngoing.add(new ActivityObserver()); taskOngoing.add(new TaskManageObserver()); task.setState(taskOngoing); } } }
|
参考
《美团博客》