工厂方法模式详解


前言

工厂方法模式是应用比较广泛的一种设计模式,它相对于简单工厂模式进行了一些优化,如果再增加一个具体产品不用修改代码,也不会违反开闭原则。


一、工厂方法模式的定义

工厂方法模式也称为工厂模式,又称为虚拟构造器(Virtual Constructor)模式或多态模式,属于类创建型模式。在工厂方法模式中,父类负责定义创建对象的公共接口,而子类则负责生成具体的对象,这样做的目的是将类的实例化延迟到子类中完成,即由子类来决定究竟应该实例化哪一个类,工厂方法模式结构图如下图所示:
在这里插入图片描述
在模式结构图中,Product表示抽象产品,它定义了产品的接口;ConcreteProduct表示具体产品,它实现抽象产品的接口;Factory表示抽象工厂,它声明了工厂方法(FactoryMethod),返回一个产品;ConcreteFactory表示具体工厂,它实现工厂方法,由客户端调用,返回一个产品实例。在工厂方法模式中,工厂方法模式的核心是抽象工厂类Factory,各种具体工厂类继承抽象工厂类并实现在抽象工厂类中定义的工厂方法,从而使得客户端只关心抽象产品和抽象工厂,完全不用理会返回的是哪一种具体产品,也不用关系它是如何被具体工厂创建的。

二、举个例子

定义一个Coffee类,它是抽象产品,还有一个CoffeeFactory它是抽像工厂,还有一个具体产品AmericanCoffee继承Coffee类,同时要有一个AmericanCoffeeFactory它要继承CoffeeFactory,另外还有一个LatteeCoffee它也是具体产品需要继承Coffee,同时有一个具体工厂生产这种产品就是LatteeCoffeeFactory。它的模式结构图如下:
在这里插入图片描述
Coffee抽象类:

abstract public class Coffee {

    abstract protected void getName();

    abstract protected void addMilk();

    abstract protected void addSugar();
}

AmericanCoffee:

public class AmericanCoffee extends Coffee {

    @Override
    protected void getName() {
        System.out.println("American Coffee...");
    }

    @Override
    protected void addMilk() {
        System.out.println("add American coffee milk...");
    }

    @Override
    protected void addSugar() {
        System.out.println("add American coffee sugar...");
    }
}

LatteeCoffee:

public class LatteCoffee extends Coffee {


    @Override
    protected void getName() {
        System.out.println("Latte Coffee...");
    }

    @Override
    protected void addMilk() {
        System.out.println("add Latte Coffee milk...");
    }

    @Override
    protected void addSugar() {
        System.out.println("add Latte Coffee sugar...");
    }
}

AmericanCoffeeFactory:

public class AmericanCoffeeFactory extends CoffeeFactory {

    @Override
    protected Coffee createCoffee() {
        return new AmericanCoffee();
    }
}

LatteeCoffeeFactory:

public class LatteeCoffeeFactory extends CoffeeFactory {

    @Override
    protected Coffee createCoffee() {
        return new LatteCoffee();
    }
}

客户端:

public class CoffeeStory {

    private static CoffeeFactory coffeeFactory;

    public static void main(String[] args) {
        CoffeeStory coffeeStory = new CoffeeStory(new AmericanCoffeeFactory());
        coffeeStory.orderCoffee();
    }

    public CoffeeStory(CoffeeFactory coffeeFactory){
        this.coffeeFactory = coffeeFactory;
    }

    public Coffee orderCoffee(){
        Coffee coffee = coffeeFactory.createCoffee();
        coffee.addMilk();
        coffee.getName();
        coffee.addSugar();
        return coffee;
    }
}

在客户端我们定义一个静态抽象工厂的引用类型,同时重载构造方法,形式参数就是抽象工厂类型,当客户端调用的时候,可以传入具体工厂类型,那么抽象工厂引用就会指向具体子类工厂,这也体现了多态的思想。

三、工厂方法模式的缺点

在系统中加入新产品时吗,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他具体工厂和具体产品,而只要添加一个具体工厂和具体产品即可,这样,系统的可扩展性也就变得非常好,符合开闭原则。但是在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,难免会增加系统类的个数,增加系统的开销。


总结

本篇就是对工厂方法模式进行的一个设计原理分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员阿坤...

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值