工厂模式(Factory Pattern)
在该模式中,创建对象时不会暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
目的:定义一个创建对象的接口,令其子类自己决定实例化哪一个类,使其创建过程延迟到子类进行。
主要解决:接口选择的问题。
何时使用:明确计划不同条件下创建不同的实例。
如何解决:让其子类实现工厂接口,返回的是一个抽象的产品。
关键代码:创建过程在子类进行。
使用场景:
1.日志记录器:用户可以选择日志记录到什么位置。
2.数据库访问:当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化的时候。
3.设计一个连接服务器的框架,可以将多个协议(POP3, IMAP, HTTP)作为产品类,共同抽象出一个接口。
注意事项:复杂对象可以使用工厂模式,简单的就直接new。因为工厂模式需要引入工厂,增加系统的开销和复杂度。
优点:
1.可以根据产品类的名称创建对象;
2.高扩展性,需要一个新的产品类的时候,直接添加一个子类就可以;
3.屏蔽产品的具体实现,只用关心产品的接口(抽象产品类)就可以。
缺点:
(由优点第2点可以得出)当系统的产品类和工厂类(用于构建产品类)过多的时候,增加了系统的复杂度。
一个工厂模式的简单代码
1 /** 2 * @author: wooch 3 * @create: 2020/02/13 4 */ 5 public class FactoryPattern { 6 public static void main(String[] args) { 7 // 创建具体的创建类对象 8 Creator creator = new ConcreteCreator(); 9 Product product = creator.creatProduct(ConcreteProduct1.class); 10 product.method1(); 11 product.method2(); 12 } 13 14 /** 15 * 定义抽象产品类 16 */ 17 static abstract class Product { 18 // 产品类的公共方法 19 public void method1() { 20 // 公共的业务逻辑 21 System.out.println("公共的业务逻辑"); 22 } 23 24 // 抽象方法 其子类实现具体的业务逻辑 25 public abstract void method2(); 26 } 27 28 /** 29 * 根据需要定义不同的具体产品类 30 */ 31 static class ConcreteProduct1 extends Product { 32 public void method2() { 33 // 具体产品类1的业务逻辑 34 System.out.println("具体产品类1的业务逻辑"); 35 } 36 } 37 38 static class ConcreteProduct2 extends Product { 39 public void method2() { 40 // 具体产品类2的业务逻辑 41 } 42 } 43 44 /** 45 * 定义抽象创建类(的工厂) 46 */ 47 static abstract class Creator { 48 // 创建对象的抽象方法 49 public abstract <T extends Product> T creatProduct(Class<T> c); 50 } 51 52 /** 53 * 定义具体的创建类,真正来创建所需的对象 54 */ 55 static class ConcreteCreator extends Creator { 56 public <T extends Product> T creatProduct(Class<T> c) { 57 Product product = null; 58 try { 59 // 通过反射技术来创建对象 60 product = (Product) Class.forName(c.getName()).newInstance(); 61 } catch (Exception e) { 62 // 异常处理 63 } 64 return (T) product; 65 } 66 } 67 }