设计模式-简单工厂模式

1、适用场景

  • 工厂类负责创建的对象比较少
  • 应用层只知道传入工厂类的参数 对于如何创建对象 创建谁的对象并不关心

    2、优点

    只需传入正确的参数 即可由工厂给我们创建对应的实例 无需了解创建的细节

    3、缺点

    增加新产品的时候 需要修改代码 违背了开闭原则


    4、Coding演示

    4.1 版本一

    UML类图预览:
    设计模式-简单工厂模式_第1张图片

    1.抽象类video

    public abstract class Video {
      /** 创建学习视频 */
      public  abstract  void produce();
    
    }

    2.JavaVideo继承抽象类 并实现抽象方法

    public class JavaVideo extends Video{
      @Override
      public void produce() {
          System.out.println("录制java学习视频中");
      }
    }

    3.PythonVideo继承抽象类 并实现抽象方法

    public class PythonVideo extends Video{
      @Override
      public void produce() {
          System.out.println("录制python学习视频");
      }
    }

    4.简单工厂类

    public class VideoFactory {
      public Video getVideo(String videoType){
          if("java".equalsIgnoreCase(videoType))
              return new JavaVideo();
          else if("python".equalsIgnoreCase(videoType))
              return new PythonVideo();
          return null;
      }
    }

    5.测试类

    public class Test {
      public static void main(String[] args) {
          VideoFactory videoFactory = new VideoFactory();
          Video java = videoFactory.getVideo("java");
          java.produce();
          Video python = videoFactory.getVideo("python");
          python.produce();
      }
    }

    输出结果:
    设计模式-简单工厂模式_第2张图片
    上述的代码结构中我们使用一个Factory类,用来帮助我们生产对应的实例,我们需要传入正确的参数,Factory可以帮助我们创建对应的实例。这就好像我们去咖啡厅喝咖啡,我们只需对watier说:"我要一杯拿铁",服务员就会自动上拿铁,而不需要我们关心制作拿铁的步骤。


    4.2 版本2

    我们发现在代码中把对应的参数写死并不符合代码的规范,也不方便维护。所以我们考虑使用反射对代码进行一下重构。

    public class VideoFactory {
      public Video getVideo(Class c){
          Video video = null;
          try {
              // Class.forName加载指定的类 
              video =   (Video)Class.forName((c.getName())).newInstance();
          } catch (InstantiationException e) {
              e.printStackTrace();
          } catch (IllegalAccessException e) {
              e.printStackTrace();
          } catch (ClassNotFoundException e) {
              e.printStackTrace();
          }
          return video;
      }
    }

    我们使用反射,根据传入的Class运行时类自动创建实例,不仅实现了同样的功能,也提升了代码的质量。


    5、扩展

    简单工厂模式在源码中的体现

    5.1 Calendar.class

    image.png
    类图:
    设计模式-简单工厂模式_第3张图片
    设计模式-简单工厂模式_第4张图片
    设计模式-简单工厂模式_第5张图片
    设计模式-简单工厂模式_第6张图片设计模式-简单工厂模式_第7张图片
    上面的这种使用方法 我们也经常在开发中使用到

5.2 在jdbc中使用

回顾一下获取jdbc连接的三步?


public class MySqlConnectionTest {
    public static void getConnection() {
        Connection conn = null;
        try {
             // 注册数据库驱动
            Class.forName("com.mysql.jdbc.Driver"); 
             // 数据库的地址
            String url = "jdbc:mysql://localhost:3306/briup";
             // 获取连接数据库的Connection对象
            conn = DriverManager.getConnection(url, "root","root");
            System.out.println("数据库连接成功!" + conn);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    public static void main(String[] args) {
        getConnection();
    }

上述代码中我们使用类名通过反射将数据库的驱动加载进来,然后通过DriverManager获取对应的连接。对mysql,orcal都是这样的步骤,因此我们来探究一下DriverManager获取连接的方法
设计模式-简单工厂模式_第8张图片设计模式-简单工厂模式_第9张图片
上述代码中通过遍历 registeredDrivers 获取对应的注册驱动。那么他是如何获取的呢?
设计模式-简单工厂模式_第10张图片
也就是说一旦这个驱动就像驱动管理DriverManager注册了我们的驱动。而我们是通过反射指定类名加载mysql的驱动,因此也就会获取mysql对应的链接



你可能感兴趣的:(设计模式java程序员)