经过上一篇文章责任链模式的设计和实现,我想大家很好理解设计模式,其实呀设计模式就是实实在在出现在我们生活当中,我们可以更好,更直白的去理解程序,也是能够更好的去和程序打交道。
今天给大家讲解策略模式基于生活最常见的实现,我现在要去某一个地方,我的方式有很多种,但是呢我的方式肯定只能选择一种,也就是我们说的特定模式的规则也就是策略。
我从湖北到云南去旅游那么我们可以抽象出共同关键点:
出行方式,出行时间
不同实现就是方式,行为不一样。价钱不一样。
方式1:徒步半年,消耗能量几十亿,欣赏风景,锻炼身体一句俩得。
方式2:骑行3个月,搞直播赚钱hh
方式3:坐高铁,8个小时。可以看书
方式4:坐飞机 3个小时。可以睡觉
步入正题:策略模式的实现是根据特定规则或者标识,根据工厂子类实现抽象父类,从而实现相同的方式不同的行为。好比小明的爸爸有3个儿子,2个女儿,都是人类,但是性别会不一样。
抽象类:
package com.xy.design.strategy.abstracts;
/**
* <p>
* 抽取公共实现方法,共同行为,旅游
* @author xy
* @since 2021-10-26
*/
public abstract class TourismAbstract {
/**
* 抽取共同行为的方法旅游
*/
public abstract String goTourism();
}
标识定义:
/**
*徒步
*/
public static String TOURISM_FOOT = "foot";
/**
* 骑行
*/
public static String TOURISM_CYSLING = "cycling";
/**
* 高铁
*/
public static String TOURISM_RAILWAY = "railway";
/**
* 飞机
*/
public static String TOURISM_PLAN = "plan";
骑行工厂:
package com.xy.design.strategy.factory.impl;
import com.xy.design.strategy.abstracts.TourismAbstract;
import com.xy.design.strategy.common.Constants;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
/**
* 骑行工厂
*/
@Service(Constants.TOURISM_CYSLING)
@Component
public class CyclingFactory extends TourismAbstract {
@Override
public String goTourism() {
return "我花了三个月骑行到了云南----------那种感觉就像90后阿秋----";
}
}
徒步工厂实现类:
package com.xy.design.strategy.factory.impl;
import com.xy.design.strategy.abstracts.TourismAbstract;
import com.xy.design.strategy.common.Constants;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
/**
* 徒步工厂实现类
*/
@Service(Constants.TOURISM_FOOT)
@Component
public class FootFactory extends TourismAbstract {
/**
* 徒步实现
* @return String
*/
@Override
public String goTourism() {
return "我花了半年徒步走到了云南----------人间值得----";
}
}
飞机工厂:
package com.xy.design.strategy.factory.impl;
import com.xy.design.strategy.abstracts.TourismAbstract;
import com.xy.design.strategy.common.Constants;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
/**
* 飞机工厂
*/
@Service(Constants.TOURISM_PLAN)
@Component
public class PlanFactory extends TourismAbstract {
@Override
public String goTourism() {
return "我花了三个小时坐飞机到云南--------中途在睡觉------";
}
}
高铁工厂:
package com.xy.design.strategy.factory.impl;
import com.xy.design.strategy.abstracts.TourismAbstract;
import com.xy.design.strategy.common.Constants;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
/**
* 高铁工厂
*/
@Service(Constants.TOURISM_RAILWAY)
@Component
public class RailwayFactory extends TourismAbstract {
@Override
public String goTourism() {
return "我花了八个小时到了云南--------------中途我在看书-----";
}
}
ApplicationContextProvider代理:
package com.xy.design.strategy.config;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* @author yang
*/
@Component
public class ApplicationContextProvider implements ApplicationContextAware {
/**
* 上下文对象实例
*/
private static ApplicationContext APPLICATION_CONTENT;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
APPLICATION_CONTENT = applicationContext;
}
/**
* 获取applicationContext
*
* @return ApplicationContext
*/
public static ApplicationContext getApplicationContext() {
return APPLICATION_CONTENT;
}
/**
* 通过name获取 Bean.
*
* @param name name
* @return Object
*/
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
/**
* 通过class获取Bean.
*
* @param clazz 类名称
* @param <T> 实例化泛型
* @return T
*/
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
/**
* 通过name,以及Clazz返回指定的Bean
*
* @param name 服务别称
* @param clazz 类名
* @param <T> 实例化泛型
* @return T
*/
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
sevice:
package com.xy.design.strategy.service;
public interface TourismService {
public String goTourism(String type);
}
seviceimpl实现类:
package com.xy.design.strategy.service;
import com.xy.design.strategy.abstracts.TourismAbstract;
import com.xy.design.strategy.config.ApplicationContextProvider;
import org.springframework.stereotype.Service;
/**
* <p>
*
* @author xy
* @since 2021-10-26
*/
@Service
public class TourismServiceImpl implements TourismService {
@Override
public String goTourism(String type) {
//这里可以使用方式方式CLASS.FORNAME方式也可以获取到子类的实现,根据包名
TourismAbstract tourismAbstract = ApplicationContextProvider.getBean(type, TourismAbstract.class);
return tourismAbstract.goTourism();
}
}
控制器:
package com.xy.design.strategy.controller;
import com.xy.design.strategy.service.TourismService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 策略控制器
*/
@RequestMapping("/strategy")
@RestController
public class StrategyController {
@Autowired
private TourismService tourismService;
@GetMapping("/tourism")
public String interview(@RequestParam String type) {
return tourismService.goTourism(type);
}
}
验证测试:
前端根据后台约定好标识,后台根据指定策略实现即可,策略模式减少代码冗余,if判断,增加代码可读性,和代码拓展性,是一个比较常用的设计模式。
策略模式应用场景:工作流,支付,代理,太多了。
是不是特别简单的一个设计模式,不难而且还简单,喜欢记得点赞把!