Java8实战[第8章]重构、测试和调试、使用Lambda表达式重构代码、以三种设计模式为例策略模式、观察者模式、模版方法

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";

    }

}

猜你喜欢

转载自blog.csdn.net/amosjob/article/details/127062084