美文网首页
策略模式和工厂模式的实践

策略模式和工厂模式的实践

作者: 掩流年 | 来源:发表于2020-03-16 23:34 被阅读0次

策略模式

策略模式可以定义为,定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。
基于一个简单的例子来看一下,假设我们明天中午吃饭有三种选择,泡面,订外卖,煮饺子。要做选择可以这么做
首先定义一个接口

interface Lunch{
  public void eat();
}

具体的实现类如下

public class InstantNoodle implements Lunch{
      public void eat(){
        //eat InstantNoodle;
    }
}

public class TakeAway implements Lunch{
      public void eat(){
        //eat takeaway;
    }
}

public class Dumplings implements Lunch{
      public void eat(){
        //eat dumplings;
    }
}

其实这时候而言,我们的功能已经算完成了。为了保证选择的封装性,便捷切换以及良好的扩展性,我们可以为他增加一个封装类,在策略模式中通常叫做Context。

public class Context{
  private Lunch lunch = null;
  public Context(Lunch lunch){
      this.lunch = lunch;
  }
  private void toEat(){
      lunch.eat();
  }
}

这时候如果第二天我选择我要吃的东西就可以使用如下方式:

public class Main{
        public static void main(String[] args) {
            //想吃泡面
            Context context = Context(new InstantNoodle());
            context.eat(); 
      }
}

对于策略模式而言,我们可以使用如下的类图来进行表示:


策略模式

优势与缺点

优点
  • 算法可以自由的切换
  • 避免多重条件的判断
  • 扩展性好
缺点
  • 策略种类多
  • 策略类需要对外暴漏

应用场景

在JDK中的ThreadPoolExecutor使用了策略模式,它预定了4中策略:

    ThreadPoolExecutor.AbortPolicy()
    ThreadPoolExecutor.CallerRunsPolicy()
    ThreadPoolExecutor.DiscardOldestPolicy()
    ThreadPoolExecutor.DiscardPolicy()

可以看到每个策略都被放在一个单独的类中

    public static class AbortPolicy implements RejectedExecutionHandler {
        /**
         * Creates an {@code AbortPolicy}.
         */
        public AbortPolicy() { }

        /**
         * Always throws RejectedExecutionException.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         * @throws RejectedExecutionException always
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() +
                                                 " rejected from " +
                                                 e.toString());
        }
    }

工厂模式

这里不再举例实际的工厂例子,实际的例子可以参照我的这篇文章

特征和优缺点

我们知道工厂模式可以分为简单工厂模式,工厂方法模式和抽象工厂模式,我们简单来讨论下他们的特点和优缺点。

简单工厂模式

优点是比较简单,简化了类的创建过程。
缺点是工厂类的扩展比较困难,不符合开闭原则。

工厂方法模式

工厂方法模式是典型的解耦框架,在new一个对象的地方可以替换,所以在所有需要生成对象的地方都可以使用。

工厂方法模式
使用案例
1.如果使用JDBC连接数据库,数据库从MySQL切换到Oracle,需要改动的地方就是切换一下驱动名称(前提条件是SQL语句是标准语句),其他的都不需要修改,这是工厂方法模式灵活性的一个直接案例。

2.在实际的单元测试应用中,如果要测试一下代码

    Class TestA{  
         public int test(){  
             DoSomeThing dst = new DoSomeThing();  
              dst.run();  
         }  
    }  

因为方法体创建的对象使用一般的Mockito是不能进行mock的,这时候我们可以构造一个工厂方法。

Class Factory{  
     public DoSomeThing build(){  
          return new DoSomeThing ();  
     }  
} 

新的代码可以写为

Class TestB{  
     Factory factory = new Factory();  
     public int test(){  
          DoSomeThing s = factory.build();  
          s.run();  
     }  
} 

这样便可以进行mock,顺利完成单元测试。

抽象工厂方法
抽象工厂

抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。

抽象工厂方法的优势

  • 封装性
  • 产品族内的约束为非公开状态

应用场景
例如一个应用,需要在三个不同平台(Windows、Linux、Android),通过抽象工厂模式屏蔽掉操作系统对应用的影响。三个不同操作系统上的软件功能、应用逻辑、UI都应该是非常类似的,唯一不同的是调用不同的工厂方法,由不同的产品类去处理与操作系统交互的信息。

相关文章

网友评论

      本文标题:策略模式和工厂模式的实践

      本文链接:https://www.haomeiwen.com/subject/qrxaehtx.html