Java版设计模式之【工厂模式】

246 阅读5分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

概述

工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际创建性工作推迟到子类中。

分类

简单工厂模式

在简单工厂模式中,工厂类处于中心位置,它可以决定哪一个产品类应当被实例化,在某种程度上实现“开-闭”原则,便于客户端相对独立的创建产品。缺点是每当又新的产品加入到系统中的时候,都需要修改工厂类,添加对应新的处理逻辑。

工厂方法模式

该模式是简单工厂模式的进一步抽象,使用了多态的特性,完善了简单工厂模式的缺点。在该模式中其核心工厂类成为一个抽象工厂,只负责限制工厂子类必须实现的功能,不再负责产品的实例化,而是将具体创建的工作交给子类进行实现,这种方式可以允许系统在不修改具体工厂类的情况下引进新的产品。

抽象工厂模式

抽象工厂模式是所有形态的工厂模式中最为抽象和最具有一般性的一种形态,其与工厂方法模式不同的地方在于工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则是面向多个产品等级结构。

起因

今天早上,公司新来的同事小张接到组长给他安排的需求,要小张根据客户不同的需求出售不同的水果,小张接到这个需求之后私下还跟我说组长小看他,就这种需求,他分分钟就敲出来了。

到了下午,我看他坐在椅子上发呆,就过去问他。

我:小伙子可以呀,早上接的任务需求这么快就搞完没事干了,在想啥呢?

小张: 哥,别笑话我了,我早上写好给组长看,直接被组长骂了一顿,还跟我说下午搞不好的话明天不用过来了。

小张:你看下我这代码,完全是按照他需求来写的,让我改我都不知道从哪下手。

public class Sellers {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你想要的水果");

        String fruit = scanner.nextLine();
        if ("apple".equals(fruit)){
            System.out.println("出售一车苹果");
        }else if ("grape".equals(fruit)){
            System.out.println("出售一车葡萄");
        }else{
            System.out.println("出售一车其它水果");
        }
    }
}

我:你这个代码怎么说呢,功能是实现了,可是有着很大的局限性。所有代码全部都写在这里,如果我需要新增一个品种的话,那又得再修改代码,维护起来比较麻烦,没有扩展性,复用性。

我:我写个模板给你参考一下吧,你再看着修改一下。

案例目标

简单工厂模式

工厂类: 根据供应商需要的水果实例化出对应的产品。

public class FruitFactory {
    public Fruit sellFruit(String fruitName){
        Fruit fruit = null;
        // 决定应被实例化的产品
        switch (fruitName) {
            case "apple":
                fruit = new Apple();
                break;
            case "grape":
                fruit = new Grape();
                break;
            default:
                fruit = new Other();
        }
        return fruit;
    }
}

产品类: 各自产品的具体实现。

public interface Fruit {
    void sell();
    void icking();
}
public class Apple implements Fruit{
    @Override
    public void sell() {
        System.out.println("出售苹果一车");
    }

    @Override
    public void icking() {
        System.out.println("采摘苹果");
    }
}
public class Grape implements Fruit{
    @Override
    public void sell() {
        System.out.println("出售葡萄一车");
    }

    @Override
    public void icking() {
        System.out.println("采摘葡萄");
    }
}
public class Other implements Fruit{
    @Override
    public void sell() {
        System.out.println("出售其它水果一车");
    }

    @Override
    public void icking() {
        System.out.println("采摘其它水果");
    }
}

客户端: 通过工厂类实现得到不同的产品。

public class Sellers {
    public static void main(String[] args) {
        FruitFactory fruitFactory = new FruitFactory();
        Fruit fruit = null;

        // 销售苹果
        fruit = fruitFactory.sellFruit("apple");
        fruit.sell();

        // 销售葡萄
        fruit = fruitFactory.sellFruit("grape");
        fruit.sell();

        // 销售其它水果
        fruit = fruitFactory.sellFruit("other");
        fruit.sell();

    }
}

工厂方法模式

抽象工厂: 限制工厂必须实现的功能。

public interface FactoryMethod {
    void sellFruit();
}

具体工厂: 各个工厂实现自己的处理流程。

public class AppleFactory implements FactoryMethod{
    @Override
    public void sellFruit() {
        Apple apple = new Apple();
        apple.icking();
        apple.sell();
    }
}
public class GrapeFactory implements FactoryMethod{
    @Override
    public void sellFruit() {
        Grape grape = new Grape();
        grape.icking();
        grape.sell();
    }
}

产品类: 与简单工厂实现一致

客户端: 通过不同工厂出售不同水果

public class Sellers {
    public static void main(String[] args) {
        FactoryMethod factory = null;

        // 苹果工厂
        factory = new AppleFactory();
        factory.sellFruit();

        // 葡萄工厂
        factory = new GrapeFactory();
        factory.sellFruit();
    }
}

抽象工厂模式

抽象工厂: 限定工厂出售的水果种类。

public abstract class AbstractFactory {
    abstract Apple getApple();
    abstract Grape getGrape();
}

具体工厂: 不同的工厂所得到的水果口味不一致。

public class BoutiqueFactory extends AbstractFactory{

    @Override
    Apple getApple() {
        return new SweetApple();
    }

    @Override
    Grape getGrape() {
        return new SweetGrape();
    }
}
public class OrdinaryFactory extends AbstractFactory {

    @Override
    Apple getApple() {
        return new SourApple();
    }

    @Override
    Grape getGrape() {
        return new SourGrape();
    }
}

产品类: 每种水果都有酸甜两种口味。

public interface Apple {
    void icking();
}
public class SweetApple implements Apple{
    @Override
    public void icking() {
        System.out.println("采集甜的苹果");
    }
}
public class SourApple implements Apple{
    @Override
    public void icking() {
        System.out.println("采集酸的苹果");
    }
}
public interface Grape {
    void icking();
}
public class SweetGrape implements Grape{
    @Override
    public void icking() {
        System.out.println("采集甜的葡萄");
    }
}
public class SourGrape implements Grape{
    @Override
    public void icking() {
        System.out.println("采集酸的葡萄");
    }
}

客户端: 在不同的工厂中分别拿到酸甜两种口味的水果。

public class Sellers {
    public static void main(String[] args) {
        AbstractFactory boutique = new BoutiqueFactory();
        AbstractFactory ordinary = new OrdinaryFactory();

        Apple boutiqueApple = boutique.getApple();
        Grape boutiqueGrape = boutique.getGrape();

        Apple ordinaryApple = ordinary.getApple();
        Grape ordinaryGrape = ordinary.getGrape();

        boutiqueApple.icking();
        boutiqueGrape.icking();

        ordinaryApple.icking();
        ordinaryGrape.icking();
    }
}

小结

简单工厂: 定义一个工厂类,由工厂类来觉得具体实例化的产品。

工厂方法: 定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。

抽象工厂: 是工厂方法的升级,为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类。