[java设计模式]工厂设计模式,给对象一个合法的生产渠道。

引言

在实际的项目中,随着我们的对象越来越多。管理的难度也越来越大。这时候怎么办呢?使用Spring容器呀!没错Spring容器也是用到了工厂设计模式。所以,我们今天就来学习一下工厂设计模式。

工厂设计模式

何为工厂设计模式?
根据名称来理解,什么是工厂?工厂就是有一堆流水线,来生产某一类的产品。假设:我们现在需要一瓶洗发水,来呵护一下我们秀美的头发。于是我们亲自动手做了一瓶:guardsman:海飞丝洗发水。用了一段时间之后,我们发现自己的头发越来越少。这个时候,我们继续一瓶 :suspect:霸王防脱洗发水,我们总不能每次都自己手动做一瓶,费时费力,还不见的效果好。那怎么办呢?当然让工厂去负责生产洗发水,我们直接通过购买获得就OK。

工厂设计模式应用场景
在写程序中,我们需要去创建某一类的一系列对象。比如:如上述,我们需要各种各样的洗发水,它们都同属于洗发水一类。

工厂设计模式的特征:

  • 调用者想创建对象,只需要调用对应的API即可。
  • 扩展性强,需要增加一个产品,只需要扩展一个工厂类即可。
  • 屏蔽产品的具体实现,调用者只关心产品的接口。

常见的工厂设计模式:

  1. 简单工厂
  2. 工厂方法
  3. 抽象工厂

具体代码实现如下:

简单工厂
简单工厂,就是通过逻辑判断,返回相应的对象。严格意义来讲,如果我们要进行扩展的时候违背了开闭原则。工作中,不建议使用,耦合性太强了。

/**
 * 洗发水产品的接口
 */
interface Shampoo {
    //... 一些洗发水的特性
}

/**
 * 海飞丝的洗发水具体实现
 */
class HeadShouldersShampoo implements Shampoo {
    //... 海飞丝洗发水的特性
}

/**
 * 霸王洗发水的具体实现
 */
class BAWANGShampoo implements Shampoo {
    //... 霸王洗发水的特性
}

/**
 * 清扬洗发水的具体实现
 */
class ClearShampoo implements Shampoo {
    //... 清扬洗发水的特性
}

/**
 * 洗发水工厂
 */
class ShampooFactory {

    // 提供对外获取Shampoo的API
    public static Shampoo getShampoo(String shampooName) {
        // 获取海飞丝洗发水对象
        if ("HeadShouldersShampoo".equalsIgnoreCase(shampooName)) {
            return new HeadShouldersShampoo();
            // 获取霸王洗发水对象
        } else if ("BAWANGShampoo".equalsIgnoreCase(shampooName)) {
            return new BAWANGShampoo();
            // 获取清扬洗发水对象
        } else if ("ClearShampoo".equalsIgnoreCase(shampooName)) {
            return new ClearShampoo();
        }
        return null;
    }
}

/**
 * @ClassName : SimpleFactory
 * @Description : 简单工厂
 */
public class SimpleFactory {
    public static void main(String[] args) {
        // 获取海飞丝洗发水对象
        Shampoo headShouldersShampoo = ShampooFactory.getShampoo("HeadShouldersShampoo");
        if (headShouldersShampoo instanceof HeadShouldersShampoo){
            System.out.println("获取海飞丝洗发水对象成功");
        }

        // 获取霸王洗发水对象
        Shampoo bawangShampoo = ShampooFactory.getShampoo("BAWANGShampoo");
        if (bawangShampoo instanceof BAWANGShampoo){
            System.out.println("获取霸王洗发水对象成功");
        }

        // 获取清扬洗发水对象
        Shampoo clearShampoo = ShampooFactory.getShampoo("ClearShampoo");
        if (clearShampoo instanceof ClearShampoo){
            System.out.println("获取清扬洗发水对象成功");
        }
    }
}

工厂方法
我们依然站在生活的角度去理解,简单工厂,就是一个工厂,来生产各种各样的洗发水。但现实生活中,这样有不操作是不现实的。我们一般会用一个工厂来生产海飞丝洗发水,一个工厂来生产霸王洗发水,一个工厂来生产清扬洗发水。此时,我们如果要新增一个品牌的洗发水,只需要增加一个工厂就好了。

// 洗发水接口
interface Shampoo{
    // ... 洗发水共有的特性
}

/**
 * 海飞丝的洗发水具体实现
 */
class HeadShouldersShampoo implements Shampoo {
    //... 海飞丝洗发水的特性
}

/**
 * 霸王洗发水的具体实现
 */
class BAWANGShampoo implements Shampoo {
    //... 霸王洗发水的特性
}

/**
 * 清扬洗发水的具体实现
 */
class ClearShampoo implements Shampoo {
    //... 清扬洗发水的特性
}

/**
 * 抽象出洗发水工厂共有的特性
 */
interface ShampooFactory{
    // 生产一瓶洗发水
    Shampoo getShampoo();
}

/**
 * 海飞丝洗发水工厂,主要负责生产海飞丝品牌的洗发水
 */
class HeadShouldersShampooFactory implements ShampooFactory{

    @Override
    public Shampoo getShampoo() {
        return new HeadShouldersShampoo();
    }
}

/**
 * 霸王洗发水工厂,主要负责生产霸王品牌的洗发水
 */
class BAWANGShampooFactory implements ShampooFactory{
    @Override
    public Shampoo getShampoo() {
        return new BAWANGShampoo();
    }
}

/**
 * 清扬洗发水工厂,主要负责生产清扬品牌的洗发水
 */
class ClearShampooFactory implements ShampooFactory{

    @Override
    public Shampoo getShampoo() {
        return new ClearShampoo();
    }
}

/**
 * @ClassName : FactoryMethod
 * @Description : 工厂方法
 */
public class FactoryMethod {

    public static void main(String[] args) {
        // 获取海飞丝洗发水,首先获取海飞丝的工厂,在获取海飞丝洗发水对象。
        // 这里肯定有小伙伴会疑惑,宁愿 new 一个海飞丝工厂,为何不直接new 海飞丝对象呢?
        // 其实结合单例设计模式,这个你可以把海飞丝工厂写成单例,就不会重复的new 海飞丝工厂了。
        Shampoo shampoo = new HeadShouldersShampooFactory().getShampoo();
        if (shampoo instanceof HeadShouldersShampoo){
            System.out.println("获取海飞丝洗发水对象成功");
        }

        // 获取霸王洗发水对象
        Shampoo shampoo1 = new BAWANGShampooFactory().getShampoo();
        if (shampoo1 instanceof  BAWANGShampoo){
            System.out.println("获取霸王洗发水对象成功");
        }

        // 获取清扬洗发水对象
        Shampoo shampoo2 = new ClearShampooFactory().getShampoo();
        if (shampoo2 instanceof ClearShampoo){
            System.out.println("获取清扬洗发水对象成功");
        }
    }
}

抽象工厂
抽象工厂,这个名字起的都很抽象。不要好理解。比较官方一点的解释:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。读起来都有点拗口。那就讲一下本博主怎么去理解?我们依然拿来生产一瓶洗发水为例子。一瓶洗发水,大致是由包装和液体组成的,在实际的生产工作中,我们不可能串行的去生产,这样太浪费时间了。于是乎,我们为了生产一瓶洗发水,就最少开两条流水线,一条生产液体,一条生产瓶子,又因为大部分的洗发水,都是由和这个两部分组成的,所以我们需要将生产液体和生产瓶子抽象出来,由每个品牌洗发水自己的流水线来实现。

import java.util.List;

/**
 * 定义洗发水接口
 */
interface Shampoo {
    // 设置洗发水的液体
    void setLiquid();

    // 设置洗发水的瓶子
    void setBox();
}

/**
 * 海飞丝的洗发水具体实现
 */
class HeadShouldersShampoo implements Shampoo {
    @Override
    public void setLiquid() {
        System.out.println("设置海飞丝洗发水有液体");
    }

    @Override
    public void setBox() {
        System.out.println("设置海飞丝洗发水的包装");
    }
    //... 海飞丝洗发水的特性
}

/**
 * 霸王洗发水的具体实现
 */
class BAWANGShampoo implements Shampoo {
    @Override
    public void setLiquid() {
        System.out.println("设置霸王洗发水液体");
    }

    @Override
    public void setBox() {
        System.out.println("设置霸王洗发水的包装");
    }
    //... 霸王洗发水的特性
}

/**
 * 清扬洗发水的具体实现
 */
class ClearShampoo implements Shampoo {
    @Override
    public void setLiquid() {
        System.out.println("设置清扬洗发水液体");
    }

    @Override
    public void setBox() {
        System.out.println("设置清扬洗发水的包装");
    }
    //... 清扬洗发水的特性
}

/**
 * 洗发水的液体接口,由各个品牌来实现
 */
interface Liquid {
}

/**
 * 海飞丝洗发水的具体实现类
 */
class HeadShouldersShampooLiquid implements Liquid {
}

/**
 * 霸王洗发水液体的具体实现类
 */
class BAWANGShampooLiquid implements Liquid {
}

/**
 * 清扬洗发水液体的具体实现类
 */
class ClearShampooLiquid implements Liquid {
}

/**
 * 洗发水包装接口,有具体品牌的子类来实现
 */
interface Box {
}

/**
 * 海飞丝的包装
 */
class HeadShouldersShampooBox implements Box {
}

/**
 * 霸王的包装
 */
class BAWANGShampooBox implements Box {
}

/**
 * 清扬的包装
 */
class ClearingShampooBox implements Box {
}

/**
 * 工厂接口
 */
interface ShampooFactory {
    // 生产液体的流水线。
    Liquid productionLiquid();

    // 生产盒子的流水线。
    Box productionBox();

    // 生产洗发水,将生产的液体和流水线组装起来。
    Shampoo getShampoo(Liquid liquid, Box box);
}

/**
 * 海飞丝洗发水的工厂
 */
class HearingShampooFactory implements ShampooFactory {

    @Override
    public Liquid productionLiquid() {
        return new HeadShouldersShampooLiquid();
    }

    @Override
    public Box productionBox() {
        return new HeadShouldersShampooBox();
    }

    @Override
    public Shampoo getShampoo(Liquid liquid, Box box) {
        return new HeadShouldersShampoo();
    }
}

/**
 * 霸王洗发水的工厂
 */
class BAWANGShampooFactory implements ShampooFactory {

    @Override
    public Liquid productionLiquid() {
        return new BAWANGShampooLiquid();
    }

    @Override
    public Box productionBox() {
        return new BAWANGShampooBox();
    }

    @Override
    public Shampoo getShampoo(Liquid liquid, Box box) {
        return new BAWANGShampoo();
    }
}

/**
 * 清扬洗发水工厂
 */
class ClearingShampooFactory implements ShampooFactory {

    @Override
    public Liquid productionLiquid() {
        return new ClearShampooLiquid();
    }

    @Override
    public Box productionBox() {
        return new ClearingShampooBox();
    }

    @Override
    public Shampoo getShampoo(Liquid liquid, Box box) {
        return new ClearShampoo();
    }
}

/**
 * @ClassName : abstractFactory 抽象工厂
 * @Description : 抽象工厂
 */
public class abstractFactory {
    public static void main(String[] args) {
        // 生产一瓶海飞丝的洗发水
        // 创建一个海飞丝的工厂
        HearingShampooFactory hearingShampooFactory = new HearingShampooFactory();
        // 生产海飞丝洗发水液体
        Liquid liquid = hearingShampooFactory.productionLiquid();
        // 生产海飞丝的包装
        Box box = hearingShampooFactory.productionBox();
        if (box instanceof HeadShouldersShampooBox && liquid instanceof HeadShouldersShampooLiquid) {
            Shampoo shampoo = hearingShampooFactory.getShampoo(liquid, box);
            if (shampoo instanceof HeadShouldersShampoo) {
                System.out.println("生产海飞丝洗发水成功");
            }
        }

        // 生产一瓶霸王的洗发水
        // 创建一个霸王的工厂
        BAWANGShampooFactory bawangShampooFactory = new BAWANGShampooFactory();
        // 生产霸王洗发水液体
        Liquid liquid1 = bawangShampooFactory.productionLiquid();
        // 生产霸王的包装
        Box box1 = bawangShampooFactory.productionBox();
        if (liquid1 instanceof BAWANGShampooLiquid && box1 instanceof BAWANGShampooBox) {
            Shampoo shampoo = bawangShampooFactory.getShampoo(liquid1, box1);
            if (shampoo instanceof BAWANGShampoo) {
                System.out.println("生产霸王洗发水成功");
            }
        }

        // 生产一瓶清扬洗发水
        // 创建一个清扬洗发水工厂
        ClearingShampooFactory clearingShampooFactory = new ClearingShampooFactory();
        // 生产清扬洗发水液体
        Liquid liquid2 = clearingShampooFactory.productionLiquid();
        // 生产清扬洗发水瓶子
        Box box2 = clearingShampooFactory.productionBox();
        if (liquid2 instanceof ClearShampooLiquid && box2 instanceof ClearingShampooBox) {
            Shampoo shampoo = clearingShampooFactory.getShampoo(liquid2, box2);
            if (shampoo instanceof ClearShampoo) {
                System.out.println("生产清扬洗发水成功");
            }
        }
    }
}

结尾

工厂设计模式,差不多就这些了。

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!