Java设计模式 之 工厂方法模式
1. 使用设计模式的好处:可提高代码的重复性,让代码更容易被他人理解,保证代码的可靠性。
2. 工厂模式定义:就是创建一个工厂类来创建你需要的类,工厂模式包括工厂模式和抽象工厂模式,抽象工厂模式是工厂模式的扩展。
3. 工厂模式意图:定义一个接口来创建对象,但是让子类来决定哪些类需要被实例化,工厂方法把实例化工作推迟到子类中去实现。
4. 工厂方法适合场景:
<1>. 有一组类似的对象需要创建
<2>. 在编码时不能预见需要创建哪种类的实例
<3>. 系统需要考虑扩展性,不应依赖产品类实例如何被创建、组合和表达的细节
5. 工厂方法类图:
代码实现,举个例子,以一汽大众汽车工厂为例,大家都知道,一汽大众可生产多款汽车,有速腾、高尔夫、CC、宝来等等,我们就是使用工厂来创建不同款式的汽车。
<1>. 创建汽车接口,该接口就有一个生产汽车抽象。
package com.dasauto.car; /** * 一汽大众汽车接口 * @author DuanCZ */ public interface ICar { /** * 生产汽车 */ public void createCar(); }
<2>. 创建速腾汽车实现类,该类实现汽车接口
package com.dasauto.car; public class SagitarCar implements ICar { /** * 生产速腾汽车 */ public void createCar() { System.out.println("-----------生产一台速腾汽车---------"); } }
<3>,创建高尔夫汽车实现类,该类实现汽车接口
package com.dasauto.car; public class GolfCar implements ICar { /** * 生产高尔夫汽车 */ public void createCar() { System.out.println("----------创建一台高尔夫汽车----------"); } }
<4>, 创建汽车工厂类,该类将根据不同款式的汽车类名称来实例化对象
package com.dasauto.car; public class CarFactory { /** * 根据类名称去创建汽车对象 * @param className * @return */ public ICar getCar(String className){ try { ICar car = (ICar) Class.forName(className).newInstance(); return car; } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } }
<5>, 模拟客户端,测试
package com.dasauto.car; public class CarClient { public static void main(String[] args) { CarFactory carFactory = new CarFactory(); ICar car = carFactory.getCar("com.dasauto.car.SagitarCar"); car.createCar(); } }
工厂方法模式很简单,就是单一的一种产品,这不同汽车类名称可以配置到xml中去,如果以后多了一种汽车,那么就是编写好实现类后,配置个XML文件,这样客户端就可以很简单的应用了。
6. 抽象工厂方法类图
相比工厂方法模式,抽象工厂就复杂一些了,它有产品族的概念,也就是说不是生产单一产品了,而是生产一系列产品。
代码实现,例如我们做一款程序,程序可能使用多种不同的数据库来完成数据持久化操作。下面是根据模型模拟代码
<1>,
package com.dcz.demo; /** * 抽象产品A * @author DuanCZ */ public interface IProductA { public void method_1(); public void method_2(); }
<2>,
package com.dcz.demo; /** * 抽象产品B * @author DuanCZ */ public interface IProductB { public void method_1(); public void method_2(); }
<3>,
package com.dcz.demo; public interface IAbstractFactory { public IProductA productA(); public IProductB productB(); }
<4>,
package com.dcz.demo; public class concretenessProductA1 implements IProductA { @Override public void method_1() { System.out.println("生产等级为1的A类Method_1"); } @Override public void method_2() { System.out.println("生产等级为1的A类Method_2"); } }
<5>,
package com.dcz.demo; public class concretenessProductA2 implements IProductA { @Override public void method_1() { System.out.println("生产等级为2的A类Method_1"); } @Override public void method_2() { System.out.println("生产等级为2的A类Method_2"); } }
<6>,
package com.dcz.demo; public class concretenessProductB1 implements IProductB { @Override public void method_1() { System.out.println("生产等级为1的B类Method_1"); } @Override public void method_2() { System.out.println("生产等级为1的B类Method_2"); } }
<7>,
package com.dcz.demo; public class concretenessProductB2 implements IProductB { @Override public void method_1() { System.out.println("生产等级为2的B类Method_1"); } @Override public void method_2() { System.out.println("生产等级为2的B类Method_2"); } }
<8>,
package com.dcz.demo; public class ConcreateFactory1 implements IAbstractFactory { public IProductA productA() { return new concretenessProductA1(); } public IProductB productB() { return new concretenessProductB1(); } }
<9>,
package com.dcz.demo; public class ConcreateFactory2 implements IAbstractFactory { @Override public IProductA productA() { return new concretenessProductA2(); } @Override public IProductB productB() { return new concretenessProductB2(); } }
<10>,
package com.dcz.demo; public class Client { public static void main(String[] args) { IAbstractFactory concreateFactory1 = new ConcreateFactory1(); IProductA productA = concreateFactory1.productA(); productA.method_1(); productA.method_2(); } }
设计原则: 要依赖抽象,不要依赖具体类