当前位置: 首页 > news >正文

01-Spring中的工厂模式

工厂模式

工厂模式的三种形态: 工厂模式是解决对象创建问题的属于创建型设计模式,Spring框架底层使用了大量的工厂模式

  • 第一种:简单工厂模式是工厂方法模式的一种特殊实现,简单工厂模式又叫静态工厂方法模式不属于23种设计模式之一
  • 第二种:工厂方法模式, 是23种设计模式之一
  • 第三种:抽象工厂模式, 是23种设计模式之一

简单/静态工厂模式

简单工厂模式的优点

  • 客户端程序不需要关心对象的创建细节,需要哪个对象时只需要向工厂索要即可, 客户端只负责消费,工厂只负责生产, 初步实现了责任的分离

简单工厂模式的缺点

  • 工厂类集中了所有产品的创造逻辑,有人把它叫做上帝类/全能类, 显然工厂类非常关键一旦出问题整个系统将瘫痪
  • 不符合OCP开闭原则,在进行系统产品扩展时需要修改工厂类的代码创建新的产品,这样客户端才能获取到扩展的产品

简单工厂模式的角色包括三个:抽象产品角色,具体产品角色, (静态)工厂类角色(提供创建对象的静态方法)

// 抽象产品角色: 武器
public abstract class Weapon {// 所有的武器都有攻击行为public abstract void attack();
}
// 具体产品角色:坦克
public class Tank extends Weapon{@Overridepublic void attack() {System.out.println("坦克开炮!");}
}
// 具体产品角色:战斗机
public class Fighter extends Weapon{@Overridepublic void attack() {System.out.println("战斗机投下原子弹!");}
}
//工厂类角色:根据不同的武器类型不同的生产武器
public class WeaponFactory {// 根据不同的武器类型生产不同的武器public static Weapon get(String weaponType){if (weaponType == null || weaponType.trim().length() == 0) {return null;}Weapon weapon = null;if ("TANK".equals(weaponType)) {weapon = new Tank();} else if ("FIGHTER".equals(weaponType)) {weapon = new Fighter();} else {throw new RuntimeException("不支持该武器!");}return weapon;}
}

编写测试程序,通过指定武器的类型从静态工厂中获取对应的武器

public class Client {public static void main(String[] args) {Weapon weapon1 = WeaponFactory.get("TANK");weapon1.attack();Weapon weapon2 = WeaponFactory.get("FIGHTER");weapon2.attack();}
}

工厂方法模式

工厂方法模式既保留了简单工厂模式的优点,同时又解决了简单工厂模式的缺点

  • 客户端程序不需要关心对象的创建细节,需要哪个对象时只需要向对应的工厂索要即可, 客户端只负责消费,工厂只负责生产
  • 如果想进行产品扩展,只需要添加一个具体产品类和一个具体工厂类,不需要修改原来的代码符合OCP原则

工厂方法模式的缺点

  • 每次增加一个产品时都需要增加一个具体类和对象实现工厂, 使得系统中类的个数成倍增加导致系统的复杂度增加,同时也增加了系统具体类的依赖

工厂方法模式的角色包括:抽象工厂角色(生产多种武器), 具体工厂角色(一个工厂对应生产一种武器), 抽象产品角色, 具体产品角色

//抽象工厂角色: 专门生产各种武器的工厂
public interface WeaponFactory {Weapon get();
}
//具体工厂角色:专门生产枪的工厂
public class GunFactory implements WeaponFactory{@Overridepublic Weapon get() {return new Gun();}}
//具体工厂角色:专门生成飞机的工厂(工厂也可以通过简单工厂模式封装成一个大工厂,然后调用其的静态方法创建对应的工厂)
public class FighterFactory implements WeaponFactory{@Overridepublic Weapon get() {return new Fighter();}
}
// 抽象产品角色: 武器类
public abstract class Weapon {// 所有武器都有攻击行为public abstract void attack();
}
// 具体产品角色:枪
public class Gun extends Weapon{@Overridepublic void attack() {System.out.println("开枪射击!");}
}
// 具体产品角色:战斗机
public class Fighter extends Weapon{@Overridepublic void attack() {System.out.println("战斗机发射核弹!");}
}

编写测试程序,获取对应的工厂创建对应的产品

public class Client {public static void main(String[] args) {// 这里的new GunFactory()可以采用简单工厂模式进行隐藏,调用WeaponFactory的静态方法根据传递的参数创建对应的工厂WeaponFactory factory = new GunFactory();Weapon weapon = factory.get();weapon.attack();WeaponFactory factory1 = new FighterFactory();Weapon weapon1 = factory1.get();weapon1.attack();}
}

新增一个匕首产品类只需要新增一个该产品对应的匕首工厂即可

// 具体产品角色:匕首
public class Dagger extends Weapon{@Overridepublic void attack() {System.out.println("切割!");}
}
//具体工厂角色:专门生产匕首的工厂
public class DaggerFactory implements WeaponFactory{@Overridepublic Weapon get() {return new Dagger();}
}
// 测试生产新增的产品类
public class Client {public static void main(String[] args) {WeaponFactory factory2 = new DaggerFactory();Weapon weapon2 = factory2.get();weapon2.attack();}
}

抽象工厂模式

工厂方法模式是针对一个产品等级结构(一个产品系列一个工厂类),而抽象工厂模式是针对多个产品等级结构(多个产品系列一个工厂类)

抽象工厂模式的优点

  • 可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象
  • 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象
  • 一个抽象工厂类可以派生出多个具体工厂类,每个具体工厂类可以创建多个具体产品类的实例

抽象工厂模式缺点

  • 产品族扩展非常困难,要增加一个系列的某一产品,既要在AbstractFactory里加代码,又要在具体的里面加代码

在这里插入图片描述

抽象工厂中包含4个角色:抽象工厂角色, 具体工厂角色, 抽象产品角色, 具体产品角色

抽象产品角色:武器产品族,水果产品族

public abstract class Weapon {// 所以武器都有攻击行为public abstract void attack();
}public abstract class Fruit {// 所有果实都有一个成熟周期public abstract void ripeCycle();
}

具体产品角色:武器产品族

// 武器产品族中的产品等级1
public class Gun extends Weapon{@Overridepublic void attack() {System.out.println("开枪射击!");}
}// 武器产品族中的产品等级2
public class Dagger extends Weapon{@Overridepublic void attack() {System.out.println("切割!");}
}// 水果产品族中的产品等级1
public class Orange extends Fruit{@Overridepublic void ripeCycle() {System.out.println("橘子的成熟周期是10个月");}
}package com.powernode.product;// 水果产品族中的产品等级2 
public class Apple extends Fruit{@Overridepublic void ripeCycle() {System.out.println("苹果的成熟周期是8个月");}
}

抽象工厂角色: 既能生产武器又能生产水果

public abstract class AbstractFactory {public abstract Weapon getWeapon(String type);public abstract Fruit getFruit(String type);
}

具体工厂角色: 武器族工厂, 水果族工厂,根据用户提供的名称创建具体的产品

// 武器族工厂
public class WeaponFactory extends AbstractFactory{public Weapon getWeapon(String type){if (type == null || type.trim().length() == 0) {return null;}if ("Gun".equals(type)) {return new Gun();} else if ("Dagger".equals(type)) {return new Dagger();} else {throw new RuntimeException("无法生产该武器");}}@Overridepublic Fruit getFruit(String type) {return null;}
}
// 水果族工厂
public class FruitFactory extends AbstractFactory{@Overridepublic Weapon getWeapon(String type) {return null;}public Fruit getFruit(String type){if (type == null || type.trim().length() == 0) {return null;}if ("Orange".equals(type)) {return new Orange();} else if ("Apple".equals(type)) {return new Apple();} else {throw new RuntimeException("我家果园不产这种水果");}}
}

测试程序

public class Client {public static void main(String[] args) {// 客户端调用方法时只面向AbstractFactory调用方法AbstractFactory factory = new WeaponFactory(); Weapon gun = factory.getWeapon("Gun");Weapon dagger = factory.getWeapon("Dagger");gun.attack();dagger.attack();AbstractFactory factory1 = new FruitFactory(); Fruit orange = factory1.getFruit("Orange");Fruit apple = factory1.getFruit("Apple");orange.ripeCycle();apple.ripeCycle();}
}
http://www.lryc.cn/news/227521.html

相关文章:

  • Linux是什么,Linux系统介绍
  • 爬虫项目(11):使用多线程对36手机高清壁纸批量抓取
  • JavaScript_动态表格_删除功能
  • 一步一步开发微信小程序(Django+Mysql)
  • mysql 讲解(1)
  • k8s关于metadata、spec.containers、spec.volumes的属性介绍(yaml格式)
  • 腾讯域名优惠卷领取
  • elastic-job 完结篇
  • 基于 Gin 的 HTTP 代理 demo
  • 【ATTCK】MITRE Caldera - 测试数据泄露技巧
  • 【数据结构】树与二叉树(十二):二叉树的递归创建(算法CBT)
  • Qt绘制网格和曲线
  • 2023-11-12
  • [工业自动化-16]:西门子S7-15xxx编程 - 软件编程 - 西门子仿真软件PLCSIM
  • 运行npm install卡住不动的几种解决方案
  • [Android]_[初级]_[配置gradle的环境变量设置安装位置]
  • docker更改存储目录原因及方案
  • HTTPS的工作流程
  • C++语言的广泛应用领域
  • Lambertian模型(完美漫反射)
  • MATLAB的编程与应用,匿名函数、嵌套函数、蒙特卡洛法的掌握与使用
  • NFS服务器的搭建
  • 安卓Frida 常用脚本
  • 机器学习数据预处理——Word2Vec的使用
  • 面试算法常考题之-------逆波兰式合集
  • 独热编码和Word2Vec的区别
  • RestTemplate.postForEntity 方法进行 HTTP POST 请求
  • 盘点双11!阿里妈妈助这些品牌短视频赢增长!
  • 内网可达网段探测netspy- Mac环境
  • Liunx命令汇总