java使用策略模式去除if和else和日志处理

策略模式:定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化

策略模式在我们的应用场景中,主要应用在两个场景:

场景一:日志存储的问题,一般我们的日志信息都会存放在了elk或者mysql中,但是我们不能保证我们的elk和mysql一直没出现问题,那么问题来了,如果我们的持久化崩溃不可用了咋办,别着急,我们需要有备用的持久化方案,简单的方法就是切换到了文件,以文件的形式进行持久化,然后数据库恢复之后进行定时的将文件持久化到数据库中,保证了日志的不丢失;而如果数据库恢复正常了又可以直接持久化到数据库中,不用繁琐的进行人工的操作

场景二:我们在写代码的时候,难免会出现很多的if和else的问题,如果我们想优化代码,使用更优雅一点,那么也可以使用策略模式来进行,根据不同的策略调用不同的方法,实现不同的效果。

对了,我先介绍一下策略模式要记住的三个单词:

(1)Strateg:策略,需要定义一个策略接口,用于实现每个策略的具体的内容,每个策略的内容需要实现这个接口和方法

(2)Context:上下文,用于处理使用哪一种策略

(3)Controller:控制层调用了哈哈哈

下面进行场景一的代码示范,直接复制就可以运行了哈:

场景一:

(1)定义一个日志策略接口

public interface LogStrategy {
    /**

     * 记录日志

     * @param msg 需记录的日志信息

     */

    public String log(String msg);
}

(2)我们有两种方法持久化,正常入库流程,非正常文件持久化流程;所以我们定义两个类实现LogStrategy接口

(2.1)定义数据库类并实现LogStrategy

public class DbLog implements LogStrategy{
    @Override
    public String log(String msg) {
        System.out.println("现在把 '"+msg+"' 记录到数据库中");
        return "数据库";

    }


}

(2.2)定义文件类并实现LogStrategy

/**

 * 把日志记录到文件

 */

public class FileLog implements LogStrategy{
    @Override
    public String log(String msg) {

        System.out.println("现在把 '"+msg+"' 记录到文件中");
        return "文件";
    }

}

(三).好了,我们现在来进行第三步了,定义上下文类

public class LogContext {
    public String  log(String  msg){
        LogStrategy logStrategy=new DbLog();
        String falge="";
        try{
            //正常的时候会走 数据入库的操作;出现异常之后就会使用文件下发的模式进行文件的下发进行持久化操作,保证日志的完整
            falge=  logStrategy.log(msg);
        }catch (Exception e){
            logStrategy=new FileLog();
            falge= logStrategy.log(msg);
        }
        return falge;
    }
}

注意:这里我们使用的是try和catch;为什么这样操作呢?因为这样日志默认进来的时候就进行数据库的入库流程;只有数据库异常了之后,就会执行catch方法,就会执行文件持久化方式,这样就保证了日志不丢失的问题,还有一个好处是数据库恢复了之后,日志又继续进行了数据库的入库的流程,保障了系统的可用。

(四)控制层调用

@Controller
@RequestMapping("log")
public class LogController {
    @ResponseBody
    @RequestMapping("test")
    public String logtest(@Param("msg")String msg){
        LogContext logContext=new LogContext();
       return logContext.log(msg);
    }
}

场景二

应用场景:减少方法中的if和else;我们在使用转发功能的时候,会转发到不同的应用,假设我们目前的需求是需要转发到新浪和微信;但是后续接入应用中心一多起来,我们就可能转发到更多的应用中心了,如果是这样的话,按照我们之前的常规的方法就是在同一个方法里面增加if和else来进行判断,这样的话少量的if还好,如果是很多的if的话,那么就很容易产生bug;这时候我们就可以使用策略模式来进行改造

上代码:

(1)定义个转发策略接口DealStrategy

public interface DealStrategy{
    String dealMythod(String option);
}

(2)新浪和微信实现这个接口和方法进行不同策略的处理

public class DealSina implements DealStrategy{
    @Override
    public String dealMythod(String option) {
      return "DealSina";
    }

}
public class DealWeChat implements DealStrategy{
    @Override
    public String dealMythod(String option) {
     return "DealWeChat";
    }
}

(3)定义上下文,进行策略的归属

import java.util.ArrayList;
import java.util.List;

public class StrategyContext {
    //静态代码块,先加载所有的策略
    protected static List<DealContext> algs = new ArrayList();
    static {
        algs.add(new StrategyContext.DealContext("Sina",new DealSina()));
        algs.add(new StrategyContext.DealContext("WeChat",new DealWeChat()));
    }
    public static class DealContext {
        private String type;
        private DealStrategy deal;
        public  DealContext(String type,DealStrategy deal){
            this.type = type;
            this.deal = deal;
        }
        public DealStrategy getDeal(){
            return deal;
        }
        public boolean options(String type){
            return this.type.equals(type);
        }
    }

}

(4)进行控制层的调用了

import static com.example.csv.StrategyUtil.StrategyContext.algs;

@RestController
@RequestMapping("strategy")
public class StrategyController {
        @ResponseBody
        @RequestMapping("Sina")
        public String shareOptions(String type){
             DealStrategy dealStrategy = null;
             for (StrategyContext.DealContext deal : algs) {
                if (deal.options(type)) {
                    dealStrategy = deal.getDeal();
                    break;
                }
            }
          return   dealStrategy.dealMythod(type);
        }
}

这样,就可以完成调用了;如果需要信增加策略的话,只需要新定义一个类并实现公共接口的方法,然后在static代码块中添加对应的即可

好了,策略模式完成了,代码直接复制即可!

缺点:就是有点费类哈哈哈

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
是的,可以使用策略模式来代替 if else 语句。策略模式是一种行为型设计模式,它定义了一系列的算法,并将每个算法封装起来,使它们可以相互替换。这样就可以在运行时动态地选择算法,而不必使用 if else 语句来判断。 下面是一个简单的例子,使用策略模式来计算商品的折扣价格: 首先,定义一个 DiscountStrategy 接口,其中包含一个计算折扣价格的方法: ```java public interface DiscountStrategy { double calculateDiscount(double price); } ``` 然后,实现几个具体的 DiscountStrategy 实现类,如 NoDiscountStrategy、FixedDiscountStrategy、PercentageDiscountStrategy。这些类分别表示不打折、固定金额折扣、百分比折扣等不同的折扣策略。 最后,在需要计算折扣价格的地方,使用一个 DiscountContext 来选择具体的 DiscountStrategy 实现类,并调用其 calculateDiscount 方法: ```java public class DiscountContext { private DiscountStrategy strategy; public DiscountContext(DiscountStrategy strategy) { this.strategy = strategy; } public void setStrategy(DiscountStrategy strategy) { this.strategy = strategy; } public double calculateDiscountPrice(double price) { return strategy.calculateDiscount(price); } } ``` 使用时,可以这样调用: ```java DiscountContext context = new DiscountContext(new PercentageDiscountStrategy(0.2)); double originalPrice = 100.0; double discountedPrice = context.calculateDiscountPrice(originalPrice); ``` 这样,就可以根据具体的折扣策略来计算折扣价格,而不必使用 if else 语句来判断。同时,如果需要添加新的折扣策略,只需要实现一个新的 DiscountStrategy 实现类,并在 DiscountContext 中设置即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值