在日常工作中需要用的策略模型的时候,大多可以使用工厂方法模式+策略模式+模板模式这样的设计模式的组合方式来合理开发,这样能让业务解耦许多,也同时能减少许多冗余的代码。
设计模式简单介绍
工厂方法模式
意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
主要解决:主要解决接口选择的问题。
优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
步骤:
1.创建一个接口
2创建实现接口的实体类。
3创建一个工厂,生成基于给定信息的实体类的对象。
4使用该工厂,通过传递类型信息来获取实体类的对象。
策略模式
意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
主要解决:在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。
优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。
缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。
步骤:
1.创建一个接口
2创建实现接口的实体类。
3创建 Context 类。
4使用 Context 来查看当它改变策略 Strategy 时的行为变化。
模板模式
意图:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
主要解决:一些方法通用,却在每一个子类都重新写了这一方法。
优点: 1、封装不变部分,扩展可变部分。 2、提取公共代码,便于维护。 3、行为由父类控制,子类实现。
缺点:每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。
步骤:
1创建一个抽象类,它的模板方法被设置为 final。
2创建扩展了上述类的实体类。
应用
应用实例部分代码
建一个策略service接口,这个service提供一个getType()方法,去用来在工厂方法的时候获取实例来用
创建一个工厂类,这个工厂类实现ApplicationContextAware接口,这样再重写setApplicationContext方法,这个方法会在spring启动容器的时候执行到refresh()方法里spring初始化完bean后,注入上下文时候调用的。在这里我把所有的实现策略service的实例都放到map里面且实例的type作为key,实例对象本身作为value,然后取的时候就通过getType()这个方法,判断map里的key,找出对应的策略实例进行调用。这样就是一个策略工厂了。
所有实例都要实现getType这个方法
这里又想到用模板方法,把一些方法通用写到这里面,就不用每个策略实现类都写一遍了。就首先先定义了一个抽象类去实现StrategyService,返回实现里面的方法,同时加一个抽象方法让子类来实现,这样就能实现通用的方法只写一次就可以了。同时因为这个类是抽象类,所以ApplicationContextAware里面是获取不到这个的实例的,只能获取到他不是抽象类的子类。
这样来实现 工厂方法模式+策略模式+模板模式