欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

设计模式->工厂模式

程序员文章站 2022-06-13 15:33:29
...

工厂模式也是一种常见的创建类模式,参考了网上的众多博文,本篇博文我们系统地来分析一下什么是工厂模式,为什么要采用工厂模式,以及工厂模式的发展优化。

工厂模式的发展有以下的三个阶段:

  • 简单工厂模式
  • 方法工厂模式
  • 抽象工厂模式

简单工厂模式:

我们在日常开发中,为了使系统更加符合“单一职责原则”,我们通常将对象的创建和使用分离,这样有利于对系统功能的复用和系统的维护。因此,提出了简单工厂模式这一概念。用户负责调用,即所谓的使用功能,而新建一个工厂对象,负责对象的创建工作,对象的创建细节都隐藏在工厂类中,用户无需知道创建细节。

下面我们通过一个实例来说明简单工厂模式。

有一个鞋子销售商,他负责卖Nike的运动鞋,休闲鞋和工作鞋。自然生产鞋子的工作交给工厂来做,销售商并不需要知道生产鞋子的细节,包括尺寸外观等等特征,而此处为了简便统统不表示。

此时整个系统的类图如下所示:

设计模式->工厂模式

代码实现如下:

public interface Shoes {
    public void sale();
}

public class AthleticsShoes implements Shoes {
    @Override
    public void sale() {
        System.out.println("销售了一双运动鞋");
    }
}

public class CasualShoes implements Shoes{
    @Override
    public void sale() {
        System.out.println("销售了一双休闲鞋");
    }
}

public class WorkShoes implements Shoes{
    @Override
    public void sale() {
        System.out.println("销售了一双工作鞋");
    }
}

public class ShoesFactory {
    public Shoes produceShoes(String type){
        if (type == null){
            System.out.println("不存在该鞋子类型");
            return null;
        }
        switch (type){
            case "AthleticsShoes":
                return new AthleticsShoes();
            case "CasualShoes":
                return new CasualShoes();
            case "WorkShoes":
                return new WorkShoes();
            default:
                System.out.println("不存在该鞋子类型");
                return null;
        }
    }
}

public class Saler {

    public static void main(String args[]){
        ShoesFactory factory = new ShoesFactory();
        Shoes shoes1 = factory.produceShoes("AthleticsShoes");
        Shoes shoes2 = factory.produceShoes("CasualShoes");
        Shoes shoes3 = factory.produceShoes("WorkShoes");

        shoes1.sale();
        shoes2.sale();
        shoes3.sale();

    }
}

方法工厂模式:

上面介绍了简单工厂模式,已经能够将对象的创建和使用分开。我们再来思考一下当前可能出现的问题,如果随着用户需求的变化,销售商需要卖登山鞋。在简单工厂模式下,我们需要怎么做呢?

首先,我们要新建一个登山鞋的类并实现Shoes接口,接着我们要在工厂类中修改produceShoes方法,这显然违反了“开闭原则”。因此,在简单工厂模式的思路上,提出了方法工厂模式。所谓方法工厂模式,就是进一步将工厂对象抽象,之后每新实现一个工厂类即可。

还是上面的实例,此时整个系统的类图如下:

设计模式->工厂模式

代码实现如下:

public interface Shoes {
    public void sale();
}

public class AthleticsShoes implements Shoes {

    @Override
    public void sale() {
        System.out.println("销售了一双运动鞋");
    }
}

public class CasualShoes implements Shoes {
    @Override
    public void sale() {
        System.out.println("销售了一双休闲鞋");
    }
}

public class WorkShoes implements Shoes {
    @Override
    public void sale() {
        System.out.println("销售了一双工作鞋");
    }
}

public interface ShoesFactory {
    public Shoes produceShoes();
}

public class AthleticsShoesFactory implements ShoesFactory {
    @Override
    public Shoes produceShoes() {
        return new AthleticsShoes();
    }
}

public class CasualShoesFactory implements ShoesFactory {
    @Override
    public Shoes produceShoes() {
        return new CasualShoes();
    }
}

public class WorkShoesFactory implements ShoesFactory {
    @Override
    public Shoes produceShoes() {
        return new WorkShoes();
    }
}

public class Saler {

    public static void main(String args[]){
        AthleticsShoesFactory factory1 = new AthleticsShoesFactory();
        CasualShoesFactory factory2 = new CasualShoesFactory();
        WorkShoesFactory factory3 = new WorkShoesFactory();
        Shoes shoes1 = factory1.produceShoes();
        Shoes shoes2 = factory2.produceShoes();
        Shoes shoes3 = factory3.produceShoes();

        shoes1.sale();
        shoes2.sale();
        shoes3.sale();
    }
}

抽象工厂模式:

经过上面的优化后,如果添加了新的鞋子,我们能通过新建一个鞋子类和一个工厂类来实现,这样既能够将对象创建和使用分离,同时还没有违背“开闭原则”。

这时,又有一个新的问题出现了,按照方法工厂模式的思路,当生产的产品很多时,那么相应的工厂类也有很多,整个系统就会变得庞大而难以管理,增加系统开销,怎么处理这个问题呢。于是便有了抽象工厂模式。

抽象工厂就是将工厂对象进一步抽象,我们还是通过上面的实例来说明。现在假设我们要考虑鞋子的颜色属性,分别有红色和蓝色两种颜色。所以现在分别有六种不同的鞋子,按照方法工厂的思路我们要生成六个相对应的工厂类,显然这项工作是不合理的。

我们现在来想办法看看如何改善这个情况,定义同一颜色的鞋子为一个族,之后我们就通过实现对族的扩展来实现生产更多种类的鞋子,同时工厂类的个数也不多,这是如何实现的呢。我们还是看代码。

public interface Shoes {
    public void sale();
}

public abstract class AthleticsShoes implements Shoes {
    public abstract void sale();
}

public abstract class CasualShoes implements Shoes {
    public abstract void sale();
}

public abstract class WorkShoes implements Shoes {
    public abstract void sale();
}

public class BlueAthleticsShoes extends AthleticsShoes {
    @Override
    public void sale() {
        System.out.println("销售了一双蓝色的运动鞋 ");
    }
}

public class BlueCasualShoes extends CasualShoes {
    @Override
    public void sale() {
        System.out.println("销售了一双蓝色的休闲鞋");
    }
}

public class BlueWorkShoes extends WorkShoes {
    @Override
    public void sale() {
        System.out.println("销售了一双蓝色的工作鞋");
    }
}

public class RedAthleticsShoes extends AthleticsShoes {
    @Override
    public void sale() {
        System.out.println("销售了一双红色的运动鞋");
    }
}

public class RedCasualShoes extends CasualShoes {
    @Override
    public void sale() {
        System.out.println("销售了一双红色的休闲鞋");
    }
}

public class RedWorkShoes extends WorkShoes {
    @Override
    public void sale() {
        System.out.println("销售了一双红色的工作鞋");
    }
}

public interface ShoesFactory {
    public AthleticsShoes produceAthleticsShoes();
    public CasualShoes produceCasualShoes();
    public WorkShoes produceWorkShoes();
}

public class BlueShoesFactory implements ShoesFactory {
    @Override
    public AthleticsShoes produceAthleticsShoes() {
        return new BlueAthleticsShoes();
    }

    @Override
    public CasualShoes produceCasualShoes() {
        return new BlueCasualShoes();
    }

    @Override
    public WorkShoes produceWorkShoes() {
        return new BlueWorkShoes();
    }
}

public class RedShoesFactory implements ShoesFactory {
    @Override
    public AthleticsShoes produceAthleticsShoes() {
        return new RedAthleticsShoes();
    }

    @Override
    public CasualShoes produceCasualShoes() {
        return new RedCasualShoes();
    }

    @Override
    public WorkShoes produceWorkShoes() {
        return new RedWorkShoes();
    }
}

public class Saler {
    public static void main(String args[]) {
        RedShoesFactory factory1 = new RedShoesFactory();
        BlueShoesFactory factory2 = new BlueShoesFactory();

        Shoes shoes1 = factory1.produceAthleticsShoes();
        Shoes shoes2 = factory1.produceCasualShoes();
        Shoes shoes3 = factory1.produceWorkShoes();
        Shoes shoes4 = factory2.produceAthleticsShoes();
        Shoes shoes5 = factory2.produceCasualShoes();
        Shoes shoes6 = factory2.produceWorkShoes();

        shoes1.sale();
        shoes2.sale();
        shoes3.sale();
        shoes4.sale();
        shoes5.sale();
        shoes6.sale();
    }
}

在抽象工厂模式想,加入我们随着用户需求变化新添加了一种鞋子颜色,我们只需新建三个新颜色的鞋子类和一个新颜色的工厂类,而不需要像方法工厂模式一样需要添加三个工厂了,因此抽象工厂模式在方法工厂模式上做了进一步的优化。

是不是抽象工厂模式就是万能了呢?答案当然是否定的。如果我们随着用户需求的变化,需要生产马丁靴怎么办?我们还需要去修改抽象工厂中的方法,破坏了开闭原则。所以在实现具体问题时,一开始就要确定好需求分析。

感悟:

在学习工厂模式的时候,在这里卡了好几天。时间花在哪里了呢,一方面是自己的理解能力不够强,理解得比较慢,而另一方面,我发现网上的各种博客中有很多的博客根本没有讲清楚工厂模式,有的甚至混淆了方法工厂模式和抽象工厂模式的概念。当然,我也是如此,这篇博文中或多或少会有一些我没有彻底明白的地方,可能是我理解的深度不够或者是理解错了。所以交流就显得特别重要,如果大家能看到我这篇博文,觉得有什么不合理的地方,请不吝赐教,多多交流互相进步。菜鸟也能快速的成长。

相关标签: Java