1、策略模式
策略模式属于对象的行为模式。
其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
声明策略模式接口:
/**
* 策略模式接口
* @version 1.0
* @description: TODO 策略模式
*/
public interface StrategyPatternMain {
// 执行的方法
// EntityPayInfo execute(String info);
// 另一种使用方式
boolean isTrue(String s);
}
通过接口实现两个策略:策略一
/**
* @version 1.0
* @description: TODO 策略模式
*/
public class StrategyPatternAliPay implements StrategyPatternMain{
// 封装支付宝信息
// @Override
// public EntityPayInfo execute(String info) {
// return EntityPayInfo.builder()
// .id(RandomStringUtils.randomAlphanumeric(16))
// .name("测试员01")
// .money(10.67)
// .phone("183xxx12323")
// .sex(1)
// .payType("支付宝")
// .info(info)
// .build();
// }
@Override
public boolean isTrue(String s) {
return s.matches("[a-z]+");
}
}
通过接口实现两个策略:策略二
/**
* @version 1.0
* @description: TODO 策略模式
*/
public class StrategyPatternWXPay implements StrategyPatternMain{
// 封装微信信息
// @Override
// public EntityPayInfo execute(String info) {
// return EntityPayInfo.builder()
// .id(RandomStringUtils.randomAlphanumeric(16))
// .name("测试员02")
// .money(12.67)
// .phone("183xxx12324")
// .sex(0)
// .payType("微信支付")
// .info(info)
// .build();
// }
@Override
public boolean isTrue(String s) {
return s.matches("自定义");
}
}
应用策略模式:
/**
* @version 1.0
* @description: TODO 策略模式
*/
@Slf4j
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@RequestMapping("/start01")
public class StrategyPatternStart {
private StrategyPatternMain strategyPatternMain;
public StrategyPatternStart(StrategyPatternMain main){
this.strategyPatternMain = main;
}
/**
* 灵活使用微信、支付宝对象信息
* @param info 保存的参数
* @return EntityPayInfo 返回的实体
*/
// public EntityPayInfo obtainInfo(String info){
// return strategyPatternMain.execute(info);
// }
/**
* 校验参数信息是否正确
* @param info 保存的参数
* @return boolean 返回的信息
*/
public boolean obtainInfo(String info){
return strategyPatternMain.isTrue(info);
}
@GetMapping("/test01")
public String testA(int type){
// StrategyPatternMain StrategyPatternMain;
//
// 根据传入的类型选择支付的类型
// if (type == 1)
// {
// StrategyPatternMain = new StrategyPatternAliPay();
// }
// else
// {
// StrategyPatternMain = new StrategyPatternWXPay();
// }
// StrategyPatternStart strategyPatternMain = new StrategyPatternStart(StrategyPatternMain);
// EntityPayInfo info = strategyPatternMain.obtainInfo("支付完成!");
//
// return info.toString();
/**
* 使用Lambda表达式之后
*/
StrategyPatternStart strategyPatternStart = new StrategyPatternStart((String s) -> s.matches("[a-z]+"));
System.out.println(strategyPatternStart.obtainInfo("abc"));
return "nice";
}
}
2、观察者模式
观察者模式,简单理解就是拿自己需要的,就如文章上讲的好几家报纸机构,比如《纽约时报》《卫报》以及《世界报》都订阅了新闻,他们希望当接收的新闻中包含他们感兴趣的关键字时,能得到特别通知。
声明信息提示接口:
/**
* @author jcs
* @version 1.0
* @description: TODO 观察者模式
* @date 2022/9/4 14:41
*/
public interface Observer {
// 提醒信息
String remindInfo(String message);
}
观察者一:
/**
* @version 1.0
* @description: TODO 观察者01
*/
public class ObserverSub01 implements Observer{
/**
* 收到消息提醒
* @return String
*/
@Override
public String remindInfo(String message) {
if (StringUtils.isNotBlank(message) && message.contains("java")){
return "观察者01: 已接收消息通知";
}
return "观察者01: 等候中...";
}
}
观察者二:
/**
* @version 1.0
* @description: TODO 观察者02
*/
public class ObserverSub02 implements Observer{
/**
* 收到消息提醒
* @return String
*/
@Override
public String remindInfo(String message) {
if (StringUtils.isNotBlank(message) && message.contains("hello world")){
return "观察者02: 已接收消息通知";
}
return "观察者02: 等候中...";
}
}
信息发布者:
/**
* @version 1.0
* @description: TODO 观察者模式
*/
@Slf4j
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@RequestMapping("/start03")
public class ObserverStart {
@GetMapping("/test01")
public String testA(){
List<Observer> listUser = Lists.newArrayList();
listUser.add(new ObserverSub01());
listUser.add(new ObserverSub02());
listUser.forEach(info-> System.out.println(info.remindInfo("hello java")));
return "success";
}
}
3、模版方法
如果你需要采用某个算法的框架,同时又希望有一定的灵活度,能对它的某些部分进行改进,
那么采用模板方法设计模式是比较通用的方案。好吧,这样讲听起来有些抽象。换句话说,模板
方法模式在你“希望使用这个算法,但是需要对其中的某些行进行改进,才能达到希望的效果”
时是非常有用的。
让我们从一个例子着手,看看这个模式是如何工作的。
声明抽象类,定义模版方法:
/**
* @version 1.0
* @description: TODO 模板方法
*/
public abstract class TemplateMethods {
/**
* 复习:抽象类和接口的区别
*
* 1、抽象类和接口都不能直接实例化。如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
*
* 2、抽象类要被子类继承,接口要被类实现。
*
* 3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现。
*
* 4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
*
* 5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
*
* 6、抽象方法只能申明,不能实现。
*
* 7、抽象类里可以没有抽象方法
*
* 8、如果—个类里有抽象方法,那么这个类只能是抽象类
*
* 9、抽象方法要被实现,所以不能是静态的,也不能是私有的。
*
* 10、接口可以继承接口,并且可多继承接口,但类只能单—继承。
*
* 11.接口可以通过匿名内部类实例化。接口是对动作的抽象,抽象类是对根源的抽象。抽象类表示的是,这个对象是什么。而接口表示的是,这个对象能做什么。
*/
// 校验参数是否通过
protected abstract boolean checkParams(String val);
// 返回信息
protected abstract String obtainResult();
public String execute(String val){
boolean status = checkParams(val);
if (status) {
System.out.println("true:" + obtainResult());
} else {
System.out.println("false:" + obtainResult());
}
return "执行完成...";
}
}
模版方法一:
/**
* @version 1.0
* @description: TODO 模板方法
*/
public class TemplateMethodsTemp01 extends TemplateMethods{
@Override
protected boolean checkParams(String val) {
return StringUtils.isNotBlank(val);
}
@Override
protected String obtainResult() {
return "当前执行方法temp01... ";
}
}
模版方法二:
/**
* @version 1.0
* @description: TODO 模板方法
*/
public class TemplateMethodsTemp02 extends TemplateMethods{
@Override
protected boolean checkParams(String val) {
return StringUtils.isNotBlank(val);
}
@Override
protected String obtainResult() {
return "当前执行方法temp02... ";
}
}
应用模板方法:
/**
* @version 1.0
* @description: TODO 模版方法
*/
@Slf4j
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@RequestMapping("/start02")
public class TemplateMethodsStart {
@GetMapping("/test01")
public String testA(){
TemplateMethods templateMethods1 = new TemplateMethodsTemp01();
String test01 = templateMethods1.execute("test");
System.out.println("test01:" + test01);
TemplateMethods templateMethods2 = new TemplateMethodsTemp02();
String test02 = templateMethods2.execute("");
System.out.println("test02:" + test02);
return "success";
}
}