4、设计模式之工厂模式的演进

4、设计模式之工厂模式的演进,第1张

一、简单工厂

1、这段时间开始学习设计模式,刚刚把设计模式的工厂模式看了一下,我自己有了自己的总结。

首先是简单工厂模式的演进:

起初我们想创建什么类就直接new 比如:

某机构想创建课程,先创建Java课程和python课程,那么就写代码实现:

 JavaCourse javaCourse = new JavaCourse();
        javaCourse.record();                 //        录制Java课程

        PythonCourse pythonCourse =  new PythonCourse();
        pythonCourse.record();                 //        录制PythonC课程
        
        // new ...

但是如果还有很多其他课程就还是要new 别的课程,这样写就非常简单没有设计感,未雨绸缪~

2、想要提升自己的代码写作水平我们需要进一步优化代码

由于每一个课程的方法相同,我们抽象出一个课程的接口:

public interface Course {

   void record();

}

我们开设的每一个实体类的课程都需要实现这个接口:

public class JavaCourse implements Course {

    @Override
    public void record() {
        System.out.println("录制Java课程!");
    }
}
public class PythonCourse  implements Course{

    @Override
    public void record() {
        System.out.println("录制python课程!");
    }
}

那么当我们想用的时候,就这样写:

 Course javaCourse = new JavaCourse();

 Course pythonCourse = new PythonCourse();

 javaCourse.record();

 pythonCourse.record();

3、以上我们想用谁的课程还是需要客户端层面去一个个new的,但是为了不让客户端去new创建实体类,而是关注工厂,我们开始引入简单工厂模式。

3.1.1、简单工厂模式的概念是让课程工厂去封装创建具体Java python课程的对象的接口对象ICourse过程,客户端和工厂打交道即可。

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;
        }
    }

}

那么调用是这样调用的:先创建工厂对象--然后传入课程名称

//课程工厂专注于创建对象
CourseFactory courseFactory = new CourseFactory();
ICourse java = courseFactory.create("java");
java.record();

3.1.2、进一步优化:利用反射创建对象

 public ICourse create(String className){  

 //入参是全类名("com.gupaoedu.vip.pattern.factory.JavaCourse")   太长的类名字  String
      
  try {
            if (!(null == className || "".equals(className))) {
                return (ICourse) Class.forName(className).newInstance();
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

那么调用是这样调用的:先创建工厂对象--然后传入全类名

CourseFactory factory = new CourseFactory();
ICourse course = factory.create("com.gupaoedu.vip.pattern.factory.JavaCourse");
course.record();

3.1.3、由于入参太长,进一步优化:限定了入参必须是ICourse的子类

  public ICourse create(Class clazz){  

  //升级为指定的类  Class

那么调用是这样调用的:先创建工厂对象--然后传入要创建的实体类的对象的类名字

CourseFactory factory = new CourseFactory();
ICourse course = factory.create(JavaCourse.class);
course.record();

总结:简单工厂模式是以上三种方法的演变。简单工厂就是他一个课程工厂(里面的创建方法的返回值是所有课程的接口对象)就可以将所有的课程自己创建出来。可以实现麻雀虽小五脏俱全的说法。

二、工厂方法

1、当简单工厂创建的对象越来越多,全国都让他去创建不同的工厂, 那么他自己一个工厂就忙不过来了,所以需要扩大规模,让自己成为抽象工厂,开更多的加盟工厂来实现这个自己的方法 ,让每一个加盟工厂生产自己品牌,那么就衍生出了工厂方法。具体代码如下:

2.1、我们先有接口接口工厂:

/**
 * 工厂模型
 * Created by Tom.
 */
public interface ICourseFactory {

    ICourse create();

}

2.2、我们再有加盟的工厂实体工厂

public class PythonCourseFactory implements ICourseFactory {

    public ICourse create() {
        return new PythonCourse();
    }
}


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

2.3、我们再有细节零部件类

public interface ICourse {
    /**
     * 录制视频
     * @return
     */
    void record();
}
public class PythonCourse implements ICourse {

    public void record() {
        System.out.println("录制Python课程");
    }
}
public class JavaCourse implements ICourse {

    public void record() {
        System.out.println("录制Java课程");
    }
}

2.4、我们调用一下:

当我们录制Java课程:

ICourseFactory factory = new JavaCourseFactory();
course = factory.create();
course.record();

当我们录制python课程

ICourseFactory factory = new PythonCourseFactory();
ICourse course = factory.create();
course.record();

三、抽象工厂

当业务范围不断增加,Java课程工厂不再这是录制课程,还有非常多的业务,比如上传笔记,发送预习资料,传送代码等等很多功能,那么我们就把其他功能先抽象出一个接口,根据每一个种类去实现这个接口,比如INote接口,JavaNote pythonNote去实现这个接口, INote 作为工厂类的一个方法返回值而已。但是我们有个总的抽象类工厂,把这写方法写在此抽象工厂的方法里,这样就扩大了业务范围。提示:抽象工作不符合开闭原则,但是扩展性非常强。

3.1、我们现有抽象工厂方法

/**
 * 抽象工厂是用户的主入口
 * 在Spring中应用得最为广泛的一种设计模式
 * 易于扩展
 */
public abstract class CourseFactory {

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

    protected abstract INote createNote();

    protected abstract IVideo createVideo();

    protected abstract ICourse create();

}

3.2、再把接口定义好

public interface ICourse {
    /**
     * 录制视频
     * @return
     */
    void record();
}

public interface INote {
    void edit();
}

public interface IVideo {
    void record();
}

3.3、实现接口的类

public class JavaCourse implements ICourse {

    public void record() {
        System.out.println("录制Java课程");
    }
}
public class PythonNote implements INote {

    public void edit() {
        System.out.println("编写Python笔记");
    }
}

3.4、创建用户可以接触到的工厂

@@1
public class JavaCourseFactory extends CourseFactory {
    public INote createNote() {
        super.init();
        return new JavaNote();
    }
    public IVideo createVideo() {
        super.init();
        return new JavaVideo();
    }
    protected ICourse create() {
        super.init();
        return new JavaCourse();}}
@@2
public class PythonCourseFactory extends CourseFactory {
    public INote createNote() {
        super.init();
        return new PythonNote();
    }
    public IVideo createVideo() {
        super.init();
        return new PythonVideo();
    }
    protected ICourse create() {
        super.init();
        return new PythonCourse();
    }
}

3.5、最后我们应该怎么调用呢?

当Java课程需要笔记和视频:

JavaCourseFactory factory = new JavaCourseFactory();
factory.createNote().edit();     // 可以写笔记
factory.createVideo().record();  //可以录视频

使用了简单工厂模式的有几下几种常见的类:

Calendar.getInstance();
LoggerFactory.getLogger("");

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1294902.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)