设计模式:工厂模式

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-08 14:22:24

一、简单工厂模式

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

1、产品类的接口及实现类

    接口:

public interface ICourse {

    void study();
}

    实现类:

public class JavaCourse implements ICourse {
    @Override
    public void study() {
        System.out.println("study java");
    }
}

2、工厂类

    工厂类根据传入的ICourse接口的子类的类型来构造实例:

public class CourseFactory {

    public ICourse create(Class<? extends ICourse> type) {
        if (type == null) {
            return null;
        }
        try {
            return type.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

3、应用

public class SimpleFactoryMain {

    public static void main(String[] args) {
        CourseFactory factory = new CourseFactory();
        ICourse course = factory.create(JavaCourse.class);
        course.study();
    }
}

4、简单工厂模式的不足

    随着接口的实现类越来越多,当出现创建方式与其他实现类不同的实现类时,简单工厂模式将很难维护。

二、工厂方法模式

    工厂方法模式主要解决产品扩展的问题。

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

1、产品类的实现类

    这里在上一节的基础上,增加一个Python课程,但是需要在创建时给成员属性赋值:

public class PythonCourse implements ICourse {
    private String name;
    @Override
    public void study() {
        System.out.println("study " + name);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

2、工厂接口和实现类

    接口:

public interface ICourseFactory {

    ICourse create();
}

    JavaCourse的工厂类:

public class JavaCourseFactory implements ICourseFactory {
    @Override
    public ICourse create() {
        return new JavaCourse();
    }
}

    PythonCourse的工厂类:

public class PythonCourseFactory implements ICourseFactory {
    @Override
    public ICourse create() {
        PythonCourse course = new PythonCourse();
        course.setName("python");
        return course;
    }
}

3、应用

public class FactoryMain {
    public static void main(String[] args) {
        ICourseFactory javaCourseFactory = new JavaCourseFactory();
        ICourse javaCourse = javaCourseFactory.create();
        javaCourse.study();

        ICourseFactory pythonCourseFactory = new PythonCourseFactory();
        ICourse pythonCourse = pythonCourseFactory.create();
        pythonCourse.study();
    }
}

4、优缺点

4.1 适用场景

1、创建对象需要大量重复的代码;

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

3、一个类通过其子类来指定创建哪个对象:在不同的子类中适用不同产品类的工厂类,来创建不同的产品类。

4.1 工厂方法模式的不足

1、产品类的增多会直接导致类个数的增加,类个数过多会增加复杂度;

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

三、抽象工厂模式

     抽象工厂模式,指的是提供一个创建一系列相关或者相互依赖对象的接口,无须指定它们的具体类。要求客户端不依赖于产品类实例如何被创建、如何被实现,强调属于一个产品族的一系列相关的产品对象,一起使用创建对象需要大量重复的代码。

1、产品族和产品等级

    一个系列的产品,被称为一个产品族的产品,例如Java课程中的JavaVideoCourse、JavaBookCourse;

    属于不同产品族的同一类型产品,被称为一个产品等级的产品,例如Python课程中的PythonVideoCourse、PythonBookCourse。

1.1 Book产品等级

    Book产品等级的接口和系列产品。

    接口:

public interface IBook {

    void read();
}

    JavaBook:

public class JavaBook implements IBook {
    @Override
    public void read() {
        System.out.println("read java book");
    }
}

    PythonBook:

public class PythonBook implements IBook {
    @Override
    public void read() {
        System.out.println("read python book");
    }
}

1.2 Video产品等级

    Video产品等级的接口和系列产品。

    接口:

public interface IVideo {

    void watch();
}

    JavaVideo:

public class JavaVideo implements IVideo {
    @Override
    public void watch() {
        System.out.println("watch java video");
    }
}

    PythonVideo:

public class PythonVideo implements IVideo {
    @Override
    public void watch() {
        System.out.println("watch python video");
    }
}

2、工厂类

    每一个产品族会用于一个工厂类。

    首先需要一个抽象工厂类(工厂接口):

public interface ICourseFactory {

    IVideo createVideo();

    IBook createBook();
}

    然后创建Java产品族的工厂:

public class JavaCourseFactory implements ICourseFactory {
    @Override
    public IVideo createVideo() {
        return new JavaVideo();
    }

    @Override
    public IBook createBook() {
        return new JavaBook();
    }
}

    Python产品族的工厂:

public class PythonCourseFactory implements ICourseFactory {
    @Override
    public IVideo createVideo() {
        return new PythonVideo();
    }

    @Override
    public IBook createBook() {
        return new PythonBook();
    }
}

3、应用

public class AbstractFactoryMain {

    public static void main(String[] args) {
        ICourseFactory javaCourseFactory = new JavaCourseFactory();
        javaCourseFactory.createBook().read();
        javaCourseFactory.createVideo().watch();

        ICourseFactory pythonCourseFactory = new PythonCourseFactory();
        pythonCourseFactory.createBook().read();
        pythonCourseFactory.createVideo().watch();
    }
}

4、优缺点

4.1 优点

    抽象工厂模式可以很清晰的用来描述庞大的产品体系

4.2 缺点

1、规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂接口。当然,实际上产品等级升级是一件很正常的事情,只要不是频繁升级,这个缺点是可以接受的;

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!