通俗易懂的java设计模式之工厂模式

它的职责是将对象从new的泥潭里解救出来,隐藏对象的构造细节,实现了对象构造和具体实现的解耦。同时它又区别于Spring Ioc的控制反转,Ioc通过反射技术实现,而工厂模式只是封装了构造细节,实现还是传统的构造方法来实现,所以Ioc更加灵活。你可能就有疑问了,既然Ioc这么灵活我还考虑工厂模式干嘛,实际上工厂模式也有它的好处,详见如下表格。

我们一定要根据实际场景灵活选用,学习技术不是为了炫耀什么,而只是用合适的技术解决当下的业务仅此而已,哪怕所用技术很简单。说白了,不能为了用而用!

接下来介绍下工厂模式的几种类型:

一、简单工厂模式

我们应该明确的知道,既然是一个工厂,那么必然这个工厂不止可以生成一个产品,它应该可以根据实际需要,创造出更多的同类产品(工厂的职责要单一,这样符合单一职责的设计原则)。既然产品可以是多个,那么我们应该明确告知工厂,我们要的是哪一种产品,很显然通过一个type类型即可实现,我以一个咖啡工厂举例,代码如下:

scala 复制代码
scala复制代码public class SimpleFactoryMethod {
    public static void main(String[] args) {
        Coffee coffee = SimpleCoffeeFactory.createCoffee(2);
        coffee.drink();
    }
}
class SimpleCoffeeFactory{
    public static Coffee createCoffee(int type){
        if(type == 1){
            return new CoffeeA();
        }else {
            return new CoffeeB();
        }
    }
}
abstract class Coffee{
    public abstract void drink();
}
class CoffeeA extends Coffee{
    @Override
    public void drink() {
        System.out.println("drink A");
    }
}
class CoffeeB extends Coffee{
    @Override
    public void drink() {
        System.out.println("drink B");
    }
}

这样我们就能根据type类型是1还是2,决定工厂生产的产品是A咖啡还是B咖啡,当然这里只是举例,type类型最好使用枚举进行实现。

二、工厂方法模式

在简单工厂模式下,我们通过类型来告诉工厂我们要生产的具体产品是哪个,那还有其他的方式吗,这个时候就要用到了我们常见的接口。这样就衍生了几个概念,抽象工厂,具体工厂和具体产品。代码如下:

typescript 复制代码
typescript复制代码public class NormalFactoryMethod {
    public static void main(String[] args) {
        CoffeeFactory coffeeFactory = new AmericanCoffeeFactory();
        Coffee coffee = coffeeFactory.createCoffee();
        coffee.drink();
    }
}
// 抽象工厂
interface CoffeeFactory {
    Coffee createCoffee();
}
// 具体工厂
class LatteCoffeeFactory implements CoffeeFactory {
    // 具体产品:咖啡A
    public Coffee createCoffee() {
        return new CoffeeA();
    }
}
class AmericanCoffeeFactory implements CoffeeFactory {
    // 具体产品:咖啡B
    public Coffee createCoffee() {
        return new CoffeeB();
    }
}

这样我们在写业务代码时,仅需要决定创建A工厂还是B工厂,就能决定最终我们需要的是哪一种产品。

细心的你发现了,既然工厂都可以有个抽象工厂,那产品不能有一个抽象产品吗,答案是当然可以啦,这就是我接下来要说的抽象工厂模式。

三、抽象工厂模式

该模式中工厂有抽象工厂和具体工厂,产品有抽象产品和具体产品,它强调的是一个产品族。

例如现有一个海尔工厂,生产的产品有冰箱和电视,后来又有了一个Tcl工厂,也是生产冰箱和电视,那么它们共性的地方就是它们都生产冰箱和电视。

代码如下:

scala 复制代码
scala复制代码public class AbstractFactoryMethod {
    public static void main(String[] args) {
        CoreFactory coreFactory = new HaierFactory();
        TvCore tvCore = coreFactory.CreateTvCore();
        tvCore.show();
    }
}
// 抽象工厂
abstract class CoreFactory{
    abstract TvCore CreateTvCore();
    abstract BxCore CreateBxCore();
}
// 具体工厂(海尔工厂)
class HaierFactory extends CoreFactory{
    @Override
    TvCore CreateTvCore() {
        return new HaierTvCore();
    }
    @Override
    BxCore CreateBxCore() {
        return new HaierBxCore();
    }
}
// 具体工厂(Tcl工厂)
class TclFactory extends CoreFactory{
    @Override
    TvCore CreateTvCore() {
        return new TclTvCore();
    }
    @Override
    BxCore CreateBxCore() {
        return new TclBxCore();
    }
}
// 抽象产品(电视)
abstract class TvCore{
    public abstract void show();
}
// 具体产品(海尔电视)
class HaierTvCore extends TvCore{
    @Override
    public void show() {
        System.out.println("海尔电视");
    }
}
// 具体产品(Tcl电视)
class TclTvCore extends TvCore{
    @Override
    public void show() {
        System.out.println("Tcl电视");
    }
}
// 抽象产品(冰箱)
abstract class BxCore{
    public abstract void show();
}
// 具体产品(海尔冰箱)
class HaierBxCore extends BxCore{
    @Override
    public void show() {
        System.out.println("海尔冰箱");
    }
}
// 具体产品(Tcl冰箱)
class TclBxCore extends BxCore{
    @Override
    public void show() {
        System.out.println("Tcl冰箱");
    }
}

最终运行效果:

复制代码
海尔电视

由此可见,找到每个工厂生产的产品存在共性的地方,这个尤为重要!

结束。

相关推荐
IT_陈寒3 小时前
Vite的热更新突然不香了,排查三小时差点砸键盘
前端·人工智能·后端
子兮曰3 小时前
Agency-Agents 深度解析:400+ AI 专家的"梦之队"如何重塑开发工作流
前端·后端·vibecoding
用户8356290780514 小时前
Python 实现 PDF 文件加密与解密方法
后端·python
小满zs4 小时前
Go语言第二章(小无相功)
后端·go
用户8356290780514 小时前
使用 Python 冻结与拆分 Excel 窗格教程
后端·python
karry_k4 小时前
MyBatis批量insert-select踩坑:useGeneratedKeys=true 可能让PostgreSQL返回大量插入结果
java·后端
妙码生花4 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(十九):点选验证码代码逐行目检
前端·后端·go
贰先生4 小时前
Xiuno BBS X版 用户封禁系统
后端
karry_k4 小时前
PostgreSQL 在 MyBatis 中执行正常 SQL 失效:一次 DELETE USING 踩坑记录
java·后端
ServBay5 小时前
不会写代码也能建站?AI 时代,非技术创始人如何从零搭建自己的 Web 项目
后端·mcp