二:工厂模式详解

Spring就是一个把设计模式用得淋漓尽致的经典框架:工厂模式,装饰器模式,代理模式,委派模式,策略模式,适配器模式,模板模式,观察者模式

工厂模式详解

简单工厂模式(Simple Factory Pattern)是指由一个工厂对象决定创建出哪一种产品类的实例,但它不属于GOF 23种设计模式。简单工厂适用于工厂类负责创建的对象较少的场景,且客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心。

public interface ICourse {
    /**
     * 学习
     */
    public void learn();
}
public class JavaCourse implements ICourse {
    @Override
    public void learn() {
        System.out.println("学习java技术");
    }
}
public class PythonCourse implements ICourse {
    @Override
    public void learn() {
        System.out.println("学习Python技术");
    }
}
public class CourseFactory {
    public ICourse create(String name){
        if("java".equals(name)){
            return new JavaCourse();
        }else if ("python".equals(name)){
            return new PythonCourse();
        }else {
            return null;
        }
    }
}
public class SimpleFactoryTest {
    public static void main(String[] args) {
        //ICourse javaCourse = new JavaCourse();
        //javaCourse.learn();
        ICourse pythonCourse = new PythonCourse();
        pythonCourse.learn();
        CourseFactory courseFactory = new CourseFactory();
        ICourse iCourse = courseFactory.create("java");
        iCourse.learn();

    }
}

 

为了调用方便,可以将工厂中的create方法改为静态方法

如果要增加其他课程,都要去更改create方法,不符合开闭原则,可以对简单的工厂模式进行优化采用反射技术

做以下优化

public class CourseFactory {
    public static ICourse create(String claseName) throws Exception{
        if(!(claseName ==null || "".equals(claseName))){
            return (ICourse)Class.forName(claseName).newInstance();
        }
        return null;
    }
}
public class SimpleFactoryTest {
    public static void main(String[] args) throws Exception{
        ICourse iCourse = CourseFactory.create("com.example.test223.JavaCourse");
        iCourse.learn();

    }
}

产品不断丰富的过程中不需要修改CourseFactory的代码,但是有个问题,方法参数是字符串,可控性需要提升,而且还需要强转型,再优化

public class CourseFactory {
    public static ICourse create(Class<? extends ICourse> clazz) throws Exception{
        if(clazz != null){
            return clazz.newInstance();
        }
        return null;
    }
}
public class SimpleFactoryTest {
    public static void main(String[] args) throws Exception{
        ICourse iCourse = CourseFactory.create(JavaCourse.class);
        iCourse.learn();

    }
}

简单工厂模式在JDK源码中无处不在,如Calendar类,下面是Calendar具体创建类:

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;
}
public static Logger getLogger(String name) {
    ILoggerFactory iLoggerFactory = getILoggerFactory();
    return iLoggerFactory.getLogger(name);
}

public static Logger getLogger(Class<?> clazz) {
    Logger logger = getLogger(clazz.getName());
    if(DETECT_LOGGER_NAME_MISMATCH) {
        Class<?> autoComputedCallingClass = Util.getCallingClass();
        if(autoComputedCallingClass != null && nonMatchingClasses(clazz, autoComputedCallingClass)) {
            Util.report(String.format("Detected logger name mismatch. Given name: \"%s\"; computed name: \"%s\".", new Object[]{logger.getName(), autoComputedCallingClass.getName()}));
            Util.report("See http://www.slf4j.org/codes.html#loggerNameMismatch for an explanation");
        }
    }

    return logger;
}

简单工厂模式缺点:工厂职责相对过重,不易于拓展复杂的产品结构

工厂方法模式

定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法模式让类的实例化推迟到子类中进行。在工厂方法模式中用户只需要关心所需要的产品对应的工厂,无须关心创建细节,而且加入新的产品时符合开闭原则

public class PythonFactory implements IcourseFactory {

    @Override
    public ICourse create() {
        return new PythonCourse();
    }
}
public class JavaFactory implements IcourseFactory {
    @Override
    public ICourse create() {
        return new JavaCourse();
    }
}
public class SimpleFactoryTest {
    public static void main(String[] args) throws Exception{
        PythonFactory pythonFactory = new PythonFactory();
       ICourse python =  pythonFactory.create();
        python.learn();
        JavaFactory java = new JavaFactory();
        ICourse iCourse = java.create();
        iCourse.learn();

    }
}

工厂模式使用于一下场景

1.创建对象需要大量重复代码

2.客户端不依赖于产品类实例如何被创建,如何被实现等细节

3.一个类通过其之子类来指定创建哪个对象

缺点

1.类的数量容易过多,增加复杂度

2.增加了系统的抽象性和理解难度

抽象工厂模式

public interface IVideo {
    void record();
}
public interface IWate {
    void write();
}
public class JavaVideo implements IVideo {
    @Override
    public void record() {
        System.out.println("学习java技术");
    }
}
public class JavaWaite implements IWate {
    @Override
    public void write() {
        System.out.println("书写java知识");
    }
}
public interface CourseFactory {
    IWate crestWate();
    IVideo createVideo();
}
public class JavaCourseFactory implements CourseFactory {
    @Override
    public IWate crestWate() {
        return new JavaWaite();
    }

    @Override
    public IVideo createVideo() {
        return new JavaVideo();
    }
}

抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,无须指定他们的具体类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值