简单工厂模式

问题背景

面向接口编程:

Api api=new Imp();

上面代码中,客户端直接用new Imp()来创建实现类,存在以下问题:

  1. 面向接口编程一个重要原因是隐藏实现。new Imp()的方式将内部实现暴露给了客户端。
  2. 面向接口编程另一个重要原因解耦合。如果有新的实现类,需要改代码,没有把接口和实现完全分离。

如何只给客户端Api接口,而不让他们知道内部实现类呢?

简单工厂模式

简单工厂模式(Simple Factory Pattern):定义一个工厂类,根据参数的不同返回不同类的实例,这些实例通常都具有共同的父类或接口。

简单工厂模式是一种创建型模式,创建实例的方法一般是静态方法,因此又称为静态工厂方法模式(Static Factory Method)。

简单工厂模式的大概结构如下图:
在这里插入图片描述
Factory是最核心的部分,createApi方法用于创建Api实现类,根据不同的条件,选择不同的实现。

简单工厂模式的核心思想是让用户“选择实现”,可以通过以下方式:

  • 方法参数,如根据不同的condition值创建不同的实现类。
  • 配置文件,根据配置文件利用反射等技术动态创建实现类。

适用场景

简单工厂模式的优点:

  • 客户端避免直接创建产品对象,实现了对象创建和使用的分离。
  • 通过配置文件,可以在不修改客户端代码的情况下更换或增加新的具体产品类,在一定程度上提高了系统的灵活性。

简单工厂模式的缺点:

  • 工厂类集中了所有产品的创建逻辑,职责过重,容易违背单一职责原则。
  • 添加新产品必须修改工厂逻辑,不利于系统的扩展和维护,违背开闭原则。
  • 简单工厂模式一般使用静态工厂方法,导致工厂类无法使用继承。

简单工厂模式适用场景:

  • 客户端只知道传入工厂类的参数,对于如何创建对象并不关心。
  • 工厂类负责创建的对象比较少,工厂方法中的业务逻辑不至于太过复杂。

典型实例

Calendar

Calendar类的静态方法getInstance(TimeZone zone, Locale aLocale),通过客户端传入的Locale选择不同的实现类。

这里,Calendar同时扮演了抽象产品和工厂的角色,具体的产品是Calendar的子类。

 public static Calendar getInstance(TimeZone zone, Locale aLocale)
    {
        return 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 no known calendar type is explicitly specified,
            // perform the traditional way to create a Calendar:
            // create a BuddhistCalendar for th_TH locale,
            // a JapaneseImperialCalendar for ja_JP_JP locale, or
            // a GregorianCalendar for any other locales.
            // NOTE: The language, country and variant strings are interned.
            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;
    }

Logback中LoggerFactory的getLogger方法

接口定义:

public interface ILoggerFactory {
    Logger getLogger(String var1);
}

LoggerFactory中的getLogger方法:

public static Logger getLogger(String name) {
    ILoggerFactory iLoggerFactory = getILoggerFactory();
    return iLoggerFactory.getLogger(name);
}

public static Logger getLogger(Class clazz) {
    return getLogger(clazz.getName());
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值