工厂模式
概念
1.产品族:位于不同产品等级结构中,功能相关联的产品组成的家族;抽象产品是一个或多个,从而构成一个或多个产品族
2.抽象工厂:是具体工厂角色必须实现的接口或者必须继承的父类,它与应用程序无关,由抽象类或者接口来实现
3.具体工厂:含有和具体业务逻辑有关的代码,由应用程序调用以创建对应的具体产品的对象
4.抽象产品:是具体产品继承的父类或者是实现的接口,由抽象类或者接口来实现
5.具体产品:具体工厂角色所创建的对象实例,由具体的类来实现
层级
1.简单工厂模式:客户端 -> 具体工厂 -> 抽象产品 -> 具体产品
2.工厂模式:客户端 -> 抽象工厂(单个抽象产品) -> 具体工厂 -> 抽象产品 -> 具体产品
3.抽象工厂模式:客户端 -> 抽象工厂(复数抽象产品) -> 具体工厂 -> 抽象产品 -> 具体产品
事项
1.复杂对象适合使用工厂模式,简单对象无需使用工厂模式;如果使用工厂模式,需要引入一个工厂类,会增加系统的复杂度
2.遵循依赖抽象原则、里氏替换原则
3.目的
(1)将实例化对象的代码提取出来,放入抽象类或接口统一管理、维护
(2)变量不直接持有具体类的引用,即,在创建对象时,不用new,通过最上层的工厂去实现底层
4.抽象工厂模式、建造者模式
(1)抽象工厂模式:实现对产品家族的创建,一个产品家族是一系列产品,具有不同分类维度的产品组合,采用抽象工厂模式不需要关心构建过程,只关心什么产品由什么工厂生产即可
(2)建造者模式:要求按照指定的规范建造产品,主要目的是通过组装零配件而产生一个新产品
5.JDK 中的 Calendar 使用了简单工厂模式
简单工厂模式
1.又称静态工厂模式,定义了一个创建对象的类,由这个类来封装实例化对象的行为
2.由一个工厂对象决定创建出哪一种产品的实例,一般是使用静态方法,通过接收的参数的不同来返回不同的实例对象
3.简单工厂模式是工厂模式中最简单实用的模式
4.缺点: 对于增加新产品,不修改代码,是无法扩展的,不完全满足开闭原则
代码示例
public class Client {//客户端
public static void main(String[] args) {
AbstractProduct productA = SimpleFactory.manufacture("产品A");
AbstractProduct productB = SimpleFactory.manufacture("产品B");
productA.getType();
productB.getType();
}
}
class SimpleFactory {//简单工厂
public static AbstractProduct manufacture(String type) {
AbstractProduct product = null;
if ("产品A".equals(type)) {
product = new ProductA();
} else if ("产品B".equals(type)) {
product = new ProductB();
}
return product;
}
}
abstract class AbstractProduct {//抽象产品
public String type;
public abstract void getType();
}
class ProductA extends AbstractProduct {//具体产品A
@Override
public void getType() {
System.out.println("产品A");
}
}
class ProductB extends AbstractProduct {//具体产品B
@Override
public void getType() {
System.out.println("产品B");
}
}
工厂模式
1.定义了一个创建对象的抽象方法,由子类决定要实例化的类,即将对象的实例化推迟到子类
2.工厂模式是简单工厂模式的整合
3.简单工厂模式、工厂模式
(1)简单工厂模式:对于一个项目或者一个独立的模块,只有一个工厂类
(2)工厂模式:有一组实现了相同接口的工厂类,不同的工厂子类实现简单工厂的方法
4.优点
(1)一个调用者想创建一个对象,只要知道其名称就可以了
(2)扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以
(3)屏蔽产品的具体实现,调用者只关心产品的接口
5.缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖
6.应用场景
(1)日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志的路径
(2)数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时
(3)设计一个连接服务器的框架,需要三个协议,“POP3”、“IMAP”、“HTTP”,可以把这三个作为产品类,共同实现一个接口
代码示例
public class Client {//客户端
public static void main(String[] args) {
ConcreteFactoryA concreteFactoryA = new ConcreteFactoryA();
ConcreteFactoryB concreteFactoryB = new ConcreteFactoryB();
AbstractProduct productA = concreteFactoryA.manufacture();
AbstractProduct productB = concreteFactoryB.manufacture();
productA.getType();
productB.getType();
}
}
abstract class AbstractFactory {//抽象工厂
public abstract AbstractProduct manufacture();
}
class ConcreteFactoryA extends AbstractFactory {//具体工厂
@Override
public AbstractProduct manufacture() {
return new ProductA();
}
}
class ConcreteFactoryB extends AbstractFactory {//具体工厂
@Override
public AbstractProduct manufacture() {
return new ProductB();
}
}
abstract class AbstractProduct {//抽象产品
public String type;
public abstract void getType();
}
class ProductA extends AbstractProduct {//具体产品A
@Override
public void getType() {
System.out.println("产品A");
}
}
class ProductB extends AbstractProduct {//具体产品B
@Override
public void getType() {
System.out.println("产品B");
}
}
抽象工厂模式
1.定义了一个接口用于创建相关或有依赖关系的对象簇,而无需指明具体的类
2.抽象工厂模式是简单工厂模式和工厂模式的整合,即对工厂模式进一步的抽象
3.根据创建对象类型使用对应的工厂子类,将单个简单工厂类变成了工厂簇,给客户端提供一个接口,可以创建多个产品族中的产品对象
4.使用条件:系统的产品多于一个的产品族,而系统一次只消费其中某一族的产品
5.工厂方法模式、抽象工厂模式
(1)工厂方法模式:一个抽象产品类,可以派生出多个具体产品类;每个具体工厂类只能创建一个具体产品类的实例
(2)抽象工厂模式:多个抽象产品类,每个抽象产品类可以派生出多个具体产品类;一个抽象工厂类可以派生出多个具体工厂类,每个具体工厂类可以创建多个具体产品的实例
6.优点
(1)当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象
(2)产品等级易扩展
7.缺点:产品族扩展困难,要增加一个系列的某一产品,既要在抽象工厂加代码,又要在具体工厂加代码
代码示例
public class Client {//客户端
public static void main(String[] args) {
ConcreteFactoryA concreteFactoryA = new ConcreteFactoryA();
ConcreteFactoryB concreteFactoryB = new ConcreteFactoryB();
AbstractProduct productA1 = concreteFactoryA.manufacture1();
AbstractProduct productA2 = concreteFactoryA.manufacture2();
AbstractProduct productB1 = concreteFactoryB.manufacture1();
AbstractProduct productB2 = concreteFactoryB.manufacture2();
productA1.getType();
productA2.getType();
productB1.getType();
productB2.getType();
}
}
abstract class AbstractFactory {//抽象工厂
public abstract AbstractProduct manufacture1();
public abstract AbstractProduct manufacture2();
}
class ConcreteFactoryA extends AbstractFactory {//具体工厂A
@Override
public AbstractProduct manufacture1() {
return new ProductA1();
}
@Override
public AbstractProduct manufacture2() {
return new ProductA1();
}
}
class ConcreteFactoryB extends AbstractFactory {//具体工厂B
@Override
public AbstractProduct manufacture1() {
return new ProductB1();
}
@Override
public AbstractProduct manufacture2() {
return new ProductB2();
}
}
abstract class AbstractProduct {//抽象产品
public String type;
public abstract void getType();
}
abstract class ProductA extends AbstractProduct {//抽象产品A
@Override
public abstract void getType();
}
class ProductA1 extends ProductA {//具体产品A1
@Override
public void getType() {
System.out.println("产品A1");
}
}
class ProductA2 extends ProductA {//具体产品A2
@Override
public void getType() {
System.out.println("产品A2");
}
}
abstract class ProductB extends AbstractProduct {//抽象产品B
@Override
public abstract void getType();
}
class ProductB1 extends ProductB {//具体产品B1
@Override
public void getType() {
System.out.println("产品B1");
}
}
class ProductB2 extends ProductB {//具体产品B2
@Override
public void getType() {
System.out.println("产品B2");
}
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战