非GoF23种设计模式-简单工厂模式

什么是简单工厂模式

简单工厂模式不是GoF23种设计模式之一,简单工厂模式通过一个工厂类来决定具体应该实例化哪一个具体的类。

结构

  • 抽象产品 :定义了产品的规范,描述了产品的主要特性和功能。
  • 具体产品 :实现或者继承抽象产品的子类
  • 具体工厂 :提供了创建产品的方法,调用者通过该方法来获取产品。

UML类图

代码理解

抽象产品代码


public abstract class Coffee {

    public void withSugar() {
        System.out.println("加糖");
    }

    public void withMilk() {
        System.out.println("加奶");
    }

    public  abstract String getName();
}

具体产品代码

public class LatteCoffee extends Coffee{
    @Override
    public String getName(){
        return "拿铁咖啡";
    }
}
public class MochaCoffee extends Coffee{
    @Override
    public String getName(){
        return "摩卡咖啡";
    }
}

具体工厂代码

public class CoffeeShop{
    public Coffee orderCoffee(String type){
        Coffee coffee = null;
        switch (type){
            case "Latte":
                coffee = new LatteCoffee();
                break;
            case "Mocha":
                coffee = new MochaCoffee();
                break;
            default:
                System.out.println("没有你想要的咖啡");
                break;
        }

        //加配料
        if (coffee != null) {
            coffee.withMilk();
            coffee.withSugar();
        }

        return coffee;
    }

}

客户端代码

public class Client {
    public static void main(String[] args) {
        CoffeeShop coffeeShop = new CoffeeShop();
        Coffee coffee = coffeeShop.orderCoffee("Latte");
        System.out.println(coffee.getName());
    }
}

输出结果

优缺点

简单工厂模式的优点包括:

  • 实现了对象的创建和使用的分离,客户端可以免除直接创建产品对象的职责,仅仅消费产品。
  • 客户端无需知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,减少了使用者的记忆量。

缺点则包括:

  • 工厂类的职责相对比较重,如果产品种类非常多,工厂方法会变得非常复杂。
  • 当增加新产品时,需要修改工厂类,这违反了开闭原则(对扩展开放,对修改封闭)。

案例分析

JDK源码解析-Calendar类

在客户端使用Calendar.getInstance()实例化Calendar对象

public static Calendar getInstance(TimeZone zone,Locale aLocale)
{
    return createCalendar(zone, aLocale);
}

调用getInstance()方法获得 createCalendar(zone, aLocale),具体实现如下:

private static Calendar createCalendar(TimeZone zone,
                                       Locale aLocale)
{
    CalendarProvider provider =
    LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
    .getCalendarProvider();
    if (provider != null) {
        try {
            return provider.getInstance(zone, aLocale);
        } catch (IllegalArgumentException iae) {
            // fall back to the default instantiation
        }
    }

    Calendar cal = null;

    if (aLocale.hasExtensions()) {
        String caltype = aLocale.getUnicodeLocaleType("ca");
        if (caltype != null) {
            switch (caltype) {
                case "buddhist":
                    cal = new BuddhistCalendar(zone, aLocale);
                    break;
                case "japanese":
                    cal = new JapaneseImperialCalendar(zone, aLocale);
                    break;
                case "gregory":
                    cal = new GregorianCalendar(zone, aLocale);
                    break;
            }
        }
    }
    if (cal == null) {
        if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
            cal = new BuddhistCalendar(zone, aLocale);
        } else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
                   && aLocale.getCountry() == "JP") {
            cal = new JapaneseImperialCalendar(zone, aLocale);
        } else {
            cal = new GregorianCalendar(zone, aLocale);
        }
    }
    return cal;
}

使用简单工厂模式的代码:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值