设计模式 - 工厂模式

一、 简单工厂(Simple Factory Pattern)

1、概念

一个工厂对象决定创建出哪一种产品类的实力,但不属于GOF23种设计模式。

简单工厂适用于工厂类负责创建的对象较少的场景,且客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心。

2、实例

1)简单定义

csharp 复制代码
public interface ICourse {
    /**
     * 录制视频
     * @return
     */
    public void record();
}
csharp 复制代码
public class JavaCourse implements ICourse {

    public void record() {
        System.out.println("录制Java课程");
    }
}
csharp 复制代码
public class PythonCourse implements ICourse {
    public void record() {
        System.out.println("录制Python课程");
    }
}
csharp 复制代码
public class SimpleFactoryTest {
    public static void main(String[] args) {
        ICourse iCourse = new JavaCourse();
        iCourse .create("java");
    }
}

客户端也就是测试类中,依赖JavaCourse,如果业务拓展,需要增加更多的Course类型,那么客户端的依赖会变得臃肿。

2)优化1

基于上述,建议一个工厂类

csharp 复制代码
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;
        }
    }
}
csharp 复制代码
public class SimpleFactoryTest {
    public static void main(String[] args) {
        //优化一
        CourseFactory courseFactory = new CourseFactory();
        courseFactory.create("java");
    }
}

客户端的调用简单了,但是如果业务继续拓展 ,工厂中的create()就要修改代码逻辑,不符合开闭原则。还可以继续优化。

3)优化二

利用反射

csharp 复制代码
public class CourseFactory {
    public ICourse create(String className) {
        try {
            if (!(null == className || "".equals(className))) {
                return (ICourse) Class.forName(className).newInstance();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public ICourse create(Class<? extends ICourse> clazz){
        try {
            if (null != clazz) {
                return clazz.newInstance();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
}
csharp 复制代码
public class SimpleFactoryTest {
    public static void main(String[] args) {
        CourseFactory courseFactory = new CourseFactory();
        ICourse iCourse = courseFactory.create("com.SimpleFactoryPattern.SimpleTwo.JavaCourse");
        iCourse.record();

        CourseFactory courseFactory1 = new CourseFactory();
        ICourse iCourse1 = courseFactory1.create(JavaCourse.class);
        iCourse.record();
    }
}

产品的添加不再需要修改CourseFactory

3、案例

例如在Calendar类中

Calendar.getInstance()


缺点:

工厂类的职责相对过重,不易于扩展过于复杂的产品结构

二、工厂方法模式

1.概念

定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中。在工厂方法模式中用户只需要关心所需产品对应的工厂,无需关心创建细节。

2、实例

基于上面实例

csharp 复制代码
public interface ICourseFactory {
    ICourse create();
}
csharp 复制代码
public class JavaCourseFactory implements ICourseFactory {
    public ICourse create() {
        return new JavaCourse();
    }
}
csharp 复制代码
public class PythonCourseFactory implements ICourseFactory {
    public ICourse create() {
        return new PythonCourse();
    }
}
csharp 复制代码
public class FactoryMethodTest {
    public static void main(String[] args) {
        ICourseFactory factory = new PythonCourseFactory();
        ICourse course = factory.create();
        course.record();
        factory = new JavaCourseFactory();
        course = factory.create();
        course.record();
    }
}

适用场景:

  • 创建对象需要大量重复的代码
  • 客户端不依赖于产品类实例如何被创建、实现等细节
  • 一个类通过其子类来指定创建哪个对象

缺点:

  • 类的个数过多,增加复杂度
  • 增加系统的抽象性和理解难度

3、抽象工厂模式(Abastract Factory Pattern)

1、概念

提供一个创建一系列相关或者相互依赖对象的接口,无需指定具体的类。客户端不依赖于产品类实例如何被创建、实现等细节。强调的是一系列相关的产品对象(同一产品族)一起使用创建对象需要大量重复的代码,提供一个产品类的库,所有的产品以同样的接口出现,从而客户端不依赖于具体实现。

2、实例

csharp 复制代码
public interface ICourse {
    /**
     * 录制视频
     * @return
     */
    void record();
}
csharp 复制代码
public interface INote {
    void edit();
}
csharp 复制代码
public interface IVideo {
    void record();
}
csharp 复制代码
public class JavaCourse implements ICourse {

    public void record() {
        System.out.println("录制Java课程");
    }
}
csharp 复制代码
public class JavaNote implements INote {

    public void edit() {
        System.out.println("编写Java笔记");
    }
}
csharp 复制代码
public class JavaVideo implements IVideo {
    public void record() {
        System.out.println("录制Java视频");
    }
}

同理可以创建其他课程,实现接口

csharp 复制代码
public abstract class CourseFactory {

    public void init(){
        System.out.println("初始化基础数据");
    }

    protected abstract INote createNote();

    protected abstract IVideo createVideo();

}
csharp 复制代码
public class JavaCourseFactory extends CourseFactory {

    public INote createNote() {
        super.init();
        return new JavaNote();
    }

    public IVideo createVideo() {
        super.init();
        return new JavaVideo();
    }
}
csharp 复制代码
public class AbstractFactoryTest {
    public static void main(String[] args) {
        JavaCourseFactory factory = new JavaCourseFactory();
        factory.createNote().edit();
        factory.createVideo().record();
    }
}

例如就是Java作为一个产品族,Python作为一个产品族等等。如果继续拓展产品等级,比如创建代码createCode(),就需要从抽象工厂到具体工厂都需要调整,不符合开闭原则。

缺点:

  • 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口
  • 增加系统的抽象性和理解难度
相关推荐
liang89993 小时前
设计模式之装饰器模式(Decorator)
设计模式·装饰器模式
CocoaAndYy3 小时前
设计模式-适配器模式
设计模式·适配器模式
刷帅耍帅3 小时前
设计模式-适配器模式
设计模式·适配器模式
拥有一颗学徒的心5 小时前
设计模式——命令模式
设计模式·命令模式
拉里小猪的迷弟8 小时前
设计模式-结构型-常用:代理模式、桥接模式、装饰者模式、适配器模式
设计模式·代理模式·桥接模式·适配器模式·装饰器模式
CocoaAndYy10 小时前
设计模式-单例模式
单例模式·设计模式
bobostudio199512 小时前
TypeScript 设计模式之【策略模式】
前端·javascript·设计模式·typescript·策略模式
ok!ko16 小时前
设计模式之原型模式(通俗易懂--代码辅助理解【Java版】)
java·设计模式·原型模式
拉里小猪的迷弟17 小时前
设计模式-创建型-常用:单例模式、工厂模式、建造者模式
单例模式·设计模式·建造者模式·工厂模式
严文文-Chris19 小时前
【设计模式-中介者模式】
设计模式·中介者模式