1、适用场景
- 工厂类负责创建的对象比较少
应用层只知道传入工厂类的参数 对于如何创建对象 创建谁的对象并不关心
2、优点
只需传入正确的参数 即可由工厂给我们创建对应的实例 无需了解创建的细节
3、缺点
4、Coding演示
4.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(); } }
输出结果:
上述的代码结构中我们使用一个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
类图:
上面的这种使用方法 我们也经常在开发中使用到
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获取连接的方法
上述代码中通过遍历 registeredDrivers 获取对应的注册驱动。那么他是如何获取的呢?
也就是说一旦这个驱动就像驱动管理DriverManager注册了我们的驱动。而我们是通过反射指定类名加载mysql的驱动,因此也就会获取mysql对应的链接
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。