策略模式 + 工厂模式 + Spring反射
文章目录
一. 策略模式
1. 概述
该模式定义了一些里而算法, 并将每个算法封装起来, 是他们可以互相替换, 且算法的变化不会影响使用算法的客户. 策略模式属于对象行为模式, 它通过对算法进行封装, 把使用该算法的责任和算法的实现分割开来, 并委派给不同的对象对这些算法进行管理
2. 结构
- 策略模式的主要角色如下
- 抽象策略类(Strategy)类: 这是一个抽象角色, 通常有一个接口或抽象类来实现. 此角色给出所有的具体策略类所需的接口
- 具体策略(Concrete Strategy)类: 实现了抽象策略定义的接口, 提供具体的算法实现或行为
- 环境(Context)类: 持有一个策略类的引用, 最终给客户端调用
3. 案例实现
策略案例:
三种生物分别是猫, 狗, 人
三种生物对应分别吃不同的事物
-
Strategy类
public interface BiologicalStrategy { void show(); }
-
猫Concrete Strategy
public class CatStrategy implements BiologicalStrategy { @Override public void show() { System.out.println("吃猫粮"); } }
-
狗Concrete Strategy
public class DogStrategy implements BiologicalStrategy { @Override public void show() { System.out.println("吃狗粮"); } }
-
人Concrete Strategy
public class PersonStrategy implements BiologicalStrategy { @Override public void show() { System.out.println("吃饭"); } }
-
Context类
public class FoodContect { private BiologicalStrategy biologicalStrategy; public void biologicalStrategyShow() { biologicalStrategy.show(); } }
-
main方法
public static void main(String[] args) { FoodContect catFood = new FoodContect(new CatStrategy()); catFood.biologicalStrategyShow(); System.out.println("===================="); FoodContect dogFood = new FoodContect(new DogStrategy()); dogFood.biologicalStrategyShow(); System.out.println("===================="); FoodContect personFood = new FoodContect(new PersonStrategy()); personFood.biologicalStrategyShow(); }
4. 总结
- 优点
- 策略类之间可以自由切换 – 由于策略类都是先同一个接口, 所以使他们之间可以自由切换
- 易于扩展 – 增加一个新的策略只需要添加一个具体的策略类即可, 基本不需要改变原有的代码, 符合"开闭原则"
- 某特定场景下相对避免使用多重条件选择语句(if-else || switch), 充分体现面向对象思想 – 可是通过工厂模式一定程度的减少(if-else || switch)
- 缺点
- 客户端必须知道所有的策略类, 并自行决定使用哪一个策略类
- 策略模式将造成产生更多策略类, 可以通过使用享元模式在一定程度上减少对象的数量
- 使用场景
- 一个系统需要动态地再几种算法中选择一种时, 可将每个算法封装到策略类中
- 一个类定义了多种行为, 并且这些行为在这个类的操作中以多个条件语句的形式出现, 可将每个条件分支移入他们各自的策略类中以代替这些条件语句
- 系统中各算法彼此完全独立, 且要求对客户隐藏具体算法的实现细节时
- 系统要求使用算法的客户不应该知道其操作的数据时, 可用策略模式来隐藏与算法相关的数据结构
- 多个类只区别在表现行为不同, 可以使用策略模式, 在运行时动态选择具体要执行的行为
二. 工厂模式(三种: 简单工厂, 工厂方法, 抽象工厂) -> 进阶改进策略加工厂
在Java中, 万物接对象, 这些对象都需要创建, 如果创建的时候直接new该对象, 就会对该对象耦合严重, 加入我们要更换对象, 所有new对象的地方都需要修改一遍, 这显然违背了软件设计的开闭原则. 如果我们使用工厂来生产对象, 我们就只和工厂打交道就可以了, 彻底和对象解耦, 如果要更换对象, 直接在工厂里更换该对象即可, 达到了与对象解耦的目的; 所以说, 工厂模式最大的有点就是解耦
1. 简单工厂模式(不属于23中经典设计模式)
简单工厂模式不是一种设计模式, 反而是一种编程习惯
①. 结构
- 抽象产品: 定义了产品的规范, 描述了产品的主要特性和功能
- 具体产品: 实现或者集成抽象产品的子类
- 具体工厂: 提供了创建产品的方法, 调用者通过方法来创建产品
②. 实现
-
实现
simple_factory代码
public class SimpleFactory { public FoodContect createFood(String type) { FoodContect foodContect = null; foodContect = new FoodContect(new CatStrategy()); return foodContect; } }
main方法
public static void main(String[] args) { SimpleFactory simpleFactory = new SimpleFactory(); BiologicalStrategy cat = simpleFactory.createFood("cat"); cat.show(); }
我们可以通过工厂模式减少一定的耦合, 但是这里简单共产有产生了新的耦合, 违反了开闭原则, 但是我们只需要修改对应的工厂类的代码省去了其他的操作
③. 总结
-
优点
封装了创建对象的过程, 可以通过参数直接获取对象. 吧对象的创建和业务逻辑层分开, 这样以后就避免了修改客户代码, 如果要实现新产品直接修改工厂类, 而不需要在源代码中修改, 这样就降低了客户代码修改的可能性, 更加容易扩展
-
缺点
增加新产品时还是需要修改工厂类的代码, 违背了开闭原则
2. 静态工厂模式(不属于23中经典设计模式)
只是将简单工厂的方法变为静态方法这里不做具体介绍
3. 工厂方法模式
- 对于以上简单工厂和静态工厂的缺点工厂方法模式就可以完美解决, 完全遵循开闭原则
- 定义一个用于创建兑现的接口, 让子类决定实例化哪个产品类对象. 工厂方法是一个产品类的实例化延迟到其工厂的子类
① . 结构
- 工厂方法模式的主要角色:
- 抽象工厂(abstract Factory): 提供了创建产品的接口, 调用者通过她访问具体工厂的工厂方法来创建产品
- 具体工厂(ConcreteFactory:) 主要是实现抽象工厂中的抽象方法, 完成具体产品的创建
- 抽象产品(Product): 定义了产品的规范, 描述了产品的额主要特性和功能
- 具体产品(ConcreteProduct): 实现了抽象产品角色定义的接口, 由具体工厂来创建, 他同具体工厂之间一一对应
②. 实现
-
工厂方法
@NoArgsConstructor @AllArgsConstructor public class FactoryMethod { private FoodFactory foodFactory; public FoodFactory createFoodFactory() { return foodFactory; } }
-
抽象工厂
public interface FoodFactory { BiologicalStrategy createFood(); }
-
具体工厂
// cat public class CatFactory implements FoodFactory{ @Override public BiologicalStrategy createFood() { return new CatStrategy(); } } // dog public class DogFactory implements FoodFactory { @Override public BiologicalStrategy createFood() { return new DogStrategy(); } } // person public class PersonFactory implements FoodFactory { @Override public BiologicalStrategy createFood() { return new PersonStrategy(); } }
-
main方法(工厂加策略)
public static void main(String[] args) { FactoryMethod factoryMethod = new FactoryMethod(new CatFactory()); FoodFactory foodFactory = factoryMethod.createFoodFactory(); FoodContect foodContect = new FoodContect(foodFactory.createFood()); foodContect.biologicalStrategyShow(); }
③. 总结
- 优点
- 用户只需要知道具体工厂的名称就可的到索要的产品, 无需知道产品的具体创建过程
- 在系统增加新的产品时只需要添加具体产品类和对应的具体工具类, 无须对员工长进行任何修改, 满足开闭原则
- 缺点
- 每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类, 这增加了系统的复杂度
4. 抽象工厂模式
前面介绍的工厂方法模式中考虑到时一类产品的生产, 如电视机厂只生产电视机
这些工厂只生产同种类产品, 同种类产品成为同等级产品, 也就是说: 工厂方法模式只考虑生产同等级的产品, 但是在现实生活中许多工厂是综合工厂, 能生产多种类产品
①. 概念
是一种为访问类创建一个创建一组相关或相互依赖对象的接口
三. 误区 -> 工厂和策略的区别
- 用途不一样
- 工厂是创建型模式,它的作用就是创建对象;
- 策略是行为型模式,它的作用是让一个对象在许多行为中选择一种行为;
- 关注点不一样
- 一个关注对象创建
- 一个关注行为的封装
- 解决不同的问题
- 工厂模式是创建型的设计模式,它接受指令,创建出符合要求的实例;它主要解决的是资源的统一分发,将对象的创建完全独立出来,让对象的创建和具体的使用客户无关。主要应用在多数据库选择,类库文件加载等。
- 策略模式是为了解决的是策略的切换与扩展,更简洁的说是定义策略族,分别封装起来,让他们之间可以相互替换,策略模式让策略的变化独立于使用策略的客户。
- 工厂相当于黑盒子,策略相当于白盒子;