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

2023年 10月 13日 45.6k 0

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

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

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

一、简单工厂模式

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

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复制代码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复制代码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冰箱");
    }
}

最终运行效果:

海尔电视

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

结束。

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论