专栏名称: 纯洁的微笑
分享微服务实践与Java技术干货、偶尔讲讲故事。在人工智能的时代,一起学习微服务架构演进和大数据治理。
目录
相关文章推荐
普象工业设计小站  ·  秋冬呼吸感穿搭FitCheck ·  昨天  
普象工业设计小站  ·  超燃!德国艺术家用数字化技术,将中国京剧虚拟 ... ·  2 天前  
普象工业设计小站  ·  “去班味”一绝,这家“赛博华佗”用神器拯救无 ... ·  2 天前  
品牌星球BrandStar  ·  伊利春节营销出圈:抽象和玩梗是神来之笔吗?| ... ·  3 天前  
品牌星球BrandStar  ·  伊利春节营销出圈:抽象和玩梗是神来之笔吗?| ... ·  3 天前  
普象工业设计小站  ·  白菜价买大牌轻奢围巾! ·  3 天前  
51好读  ›  专栏  ›  纯洁的微笑

还在使用 if else 写代码?试试 “策略模式” 吧!

纯洁的微笑  · 公众号  ·  · 2020-05-08 15:30

正文



我们使用的app大多都有分享的功能,我们可以选择分享到不同的地方,比如微博、微信、QQ等等,虽然是同一个内容,但是分享到不同的平台就会有不同的处理方式,比如要跳转到不同的app或者直接复制链接等等。如果让你来实现这个功能,你会如何实现呢?


如果你对设计模式不熟悉,那么第一反应就是有if...else或者switch语句来进行条件判断,根据用户的不同选择而使用不同的处理方法。我们用代码简化地处理一下:
public void Share{
public void shareOptions(String option){
       if(option.equals("微博")){
           //function1();
           //...
      }else if(option.equals("微信")){
           //function2();
           //...
      }else if(option.equals("朋友圈")){
           //function3();
           //...
      }else if(option.equals("QQ")){
           //function4();
           //...
      }
       //...
}
如果只是写一个这么简单的功能,那么这样的代码也未尝不可,因为这样的代码量不多,后续也不需要怎么拓展和修改,维护起来也不算麻烦。但是,我们工作中遇到的都是一些比较复杂的项目,要保证项目的可读性、可维护性和可拓展性,就必须在代码上下功夫了。
这里我们就要提到一个概念,那就是设计模式了。设计模式是指针对软件开发过程中重复发生的问题的解决办法。其中以被称为Gang of Four(GoF)的4人整理出的23种设计模式最为有名。
当然,我不可能在这里把23种设计模式全部介绍完,就算全部介绍一遍,而且你还能全部记住,也不一定奏效。首先,你没有必要全部记下来,因为这23种设计模式并非都是经常使用到的设计模式。其次,死记硬背下这些设计模式没有任何意义,重要的是在自己脑海中理解设计模式是怎样解决问题的。
今天我们就谈谈可以优化以上问题的设计模式,策略模式(Strategy  Design Pattern)。

策略模式(Strategy  Design Pattern)

策略指的是计策、谋略,而模式一般指人为整理而成的,在某种场景下重复发生的问题的解决办法。在编程中,我们可以把策略看做是“算法”,而策略模式,按照GoF的定义,就是我们设计一些算法,把它们封装起来,让它们可以相互替换,这样就可以轻松地切换不同的算法来解决同一个问题。



我们看一下策略模式中有哪些角色。
  • Strategy(策略)Strategy角色负责决定实现策略所必需的接口(API)。在示例程序中,由strategy接口扮演此角色。

  • ConcreteStrategy(具体的策略)ConcreteStrategy角色负责实现Strategy角色的接口(API),即负责实现具体的策略(战略、方向、方法和算法)。

  • Context(上下文)负责使用Strategy角色。Context角色保存了ConcreteStrategy角色的实例,并使用ConcreteStrategy角色去实现需求(总之,还是要调用Strategy角色的接口(API))。

再看看策略模式的类图:
介绍到这里,相信你对策略模式有了初步的认识,那我们就用策略模式来重构前面的代码,让你加深对策略模式的理解。
//定义策略接口
public interface DealStrategy{
   void dealMythod(String option);
}

//定义具体的策略1
public class DealSina implements DealStrategy{
   @override
   public void dealMythod(String option){
       //...
  }
}

//定义具体的策略2
public class DealWeChat implements DealStrategy{
   @override
   public void dealMythod(String option){
       //...
  }
}

//定义上下文,负责使用DealStrategy角色
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);
   }
}


public void Share{
   private static List<
DealContext> algs = new ArrayList();
   
//静态代码块,先加载所有的策略
   
static {
       algs.add(
new DealContext("Sina",new DealSina()));
       algs.add(
new DealContext("WeChat",new DealWeChat()));
  }
public void shareOptions(String type){
       DealStrategy dealStrategy = 
null;
       
for (DealContext deal : algs) {
           
if (deal.options(type)) {
               dealStrategy = deal.getDeal();
               
break;
          }  
      }
       dealStrategy.dealMythod(type);
  }
}
再回忆一下策略模式中的各个角色,代码中的DealStrategy接口就是策略,DealSina和DealWeChat是具体的策略,DealContext就是使用策略的上下文。
所以这样的代码已经符合策略模式的代码结构了。我们通过策略模式将策略的定义、创建、使用解耦,让每一部分都不至于太复杂,也去除了if...else这样的条件判断语句,代码的可维护性和可拓展性都提高了。
我们把可变的部分放到 了Share 类中的静态代码段中。如果有新的需求,要添加一个分享的方式时,只需要定义好具体的策略,然后修改 Share 类中的静态代码段,其他代码都不需要修改。
策略模式还是比较常用的一种设计模式,比如java中给我定义好的Comparator 接口就是策略模式的一个实践。
如果需要对某个类的排序,而该类没有实现Comparable接口,那么可以建立一个实现Comparator接口的比较器即可。通过实现Comparator类来新建一个比较器,然后通过该比较器来对类进行排序。
//策略接口
public interface Comparator<T{
   int compare(T o1, T o2);
}

//需要我们来定义具体的策略
public class sorter






请到「今天看啥」查看全文