专业编程基础技术教程

网站首页 > 基础教程 正文

一天一个设计模式——简单工厂模式

ccvgpt 2024-08-16 15:06:07 基础教程 10 ℃

(零)简单工厂模式

工厂模式的使用原则就是将构造复杂对象的工作交给指定的人去做。调用者不需要关心具体如何实现,只需要传入自己想要的工厂类参数即可。简单工厂模式专门定义一个工厂类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

简单工厂模式,也叫静态工厂模式,它并不在我们常说的23种设计模式之中。

一天一个设计模式——简单工厂模式

1,简单工厂模式的设计原则:

  1. 简单工厂(SimpleFactory):负责实现所有实例的内部逻辑,由他指定该实例哪种产品。
  2. 抽象产品(IProduct):所有产品实例的顶级接口。
  3. 具体产品(ConcreteProduct):简单工厂创建的具体产品 。

下面我们以一个具体案例分析简单工厂模式的使用:

2,简单案例

同样是录制课程,现在有 Java,Python 课程等,当我们需要新增课程时如何利用简单工厂模式进行设计呢?第一步,设计 CourseFactory 负责创建课程的逻辑,可以想到它是个 if-else 或者是 switch-case 的模式;传入什么参数,工厂就实例化出什么类型的课程;第二步,创建父类接口 ICourse ,这里它只有一个方法 record 记录课程;第三步,动态的增加陆续上线的课程。

public class CourseFactory { 
	public static ICourse create(String name) {
        if("java".equals(name)){
            return new JavaCourse();
        }else if("python".equals(name)){
            return new PythonCourse();
        }else {
            return null;
        }
 	}
}
 public interface ICourse {
     void record();
 }
 public class JavaCourse implements ICourse  {
     @Override
     public void record() {
         System.out.println("录制java课程");
     }
 }
 public class PythonCourse implements ICourse {
     @Override
     public void record() {
         System.out.println("录制python课程");
     }
 }
 public class Test {
     public static void main(String[] args) {
         ICourse iCourse = CourseFactory.create("java");
         iCourse.record();
     }
 }

2.1,第一轮优化:

当我们上线新的课程时,除了增加新的课程类,还需要修改工厂中的 create 方法,违背了开闭原则 OCP ,我们采用反射机制,根据全类名动态的决定实例的对象。

 public class CourseFactory {
     public static ICourse create(String className) {
 //      2,采用反射,解决添加其他课程,需要更改工厂类的create方法的问题
        if (className != null && !"".equals(className)) {
             try {
                 return (ICourse) Class.forName(className).newInstance();
             } catch (InstantiationException e) {
                 e.printStackTrace();
             } catch (IllegalAccessException e) {
                 e.printStackTrace();
             } catch (ClassNotFoundException e) {
                 e.printStackTrace();
             }
         }
         return null;
     }
 public class Test {
     public static void main(String[] args) {
      ICourse iCourse = CourseFactory.create(
                "com.lsk.creationalPatterns.simpleFactoryPattern.JavaCourse");
         iCourse.record();
     }
 }

2.2,第二轮优化:

上一轮优化中,传入字符参数的有些臃肿而且还需要做强制类型转换,这里我们直接将参数改为类名的形式。

 public class CourseFactory {
 //       3,解决字符串参数的弊端以及强制转换的问题
     public static ICourse create(Class<? extends ICourse> clazz){
         if(clazz !=null){
             try {
                 return clazz.newInstance();
             } catch (InstantiationException e) {
                 e.printStackTrace();
             } catch (IllegalAccessException e) {
                 e.printStackTrace();
             }
         }
         return null;
     }
 }
 public class Test {
     public static void main(String[] args) {
         ICourse iCourse = CourseFactory.create(JavaCourse.class);
         iCourse.record();
     }
 }

3,简单工厂模式点评

3.1,工厂模式要点

为什么需要采用工厂模式?直接new一个不可以?

工厂模式就是将对象的创建和对象本身业务处理分开,降低耦合;

工厂模式负责产品创建的逻辑,决定对象何时进行实例,而应用层客户端只需传入参数,就可以免除创建产品的责任,直接消费产品,职责分明;

客户端不需要知道产品的具体类名,仅需要知道产品对应的参数即可,减少调用的记忆复杂度;

3.2,不足分析

1,扩展困难,添加新产品需要修改创建逻辑;

2,工厂类职责过重,一旦出现问题,整个系统都不能工作;

3,简单工厂使用了静态方法,造成工厂角色无法形成基于继承的等级结构。

3.3,适用场景

1,产品对象较少,不需要工厂维护复杂的创建逻辑;

2,客户端不关心创建细节,只需知道产品对应参数。

简单工厂模式结构简单,调用方便,非常适合需要动态增加产品的情形。作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。且当产品基数增加时,工厂类就会非常臃肿。

最近发表
标签列表