设计模式之工厂模式
工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。
工厂模式可以分为三类:
1)简单工厂模式(Simple Factory)
2)工厂方法模式(Factory Method)
3)抽象工厂模式(Abstract Factory)
这三种模式从上到下逐步抽象,并且更具一般性。
GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。
(1)简单工厂模式
背景:一个用户要生产不同类型的车,如宝马、奥迪、奔驰等,用户不用在自己的类中直接new,而是通过简单的工厂进行生产,但是成产的车辆强依赖于用户的传参需求。类图如下
/** * Open Free. * Code for Open Community, free to use! */ package designpattern.simpefactory; /** * @author admin * @version $Id Car.java, v 0.1 2015-10-18 下午1:02 admin Exp $$ */ public class Car { } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.simpefactory; /** * @author admin * @version $Id Audi.java, v 0.1 2015-10-18 下午1:06 admin Exp $$ */ public class Audi extends Car { public Audi() { System.out.println("Product AudiBusiness!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.simpefactory; import com.sun.tools.doclets.internal.toolkit.util.SourceToHTMLConverter; /** * @author admin * @version $Id Benz.java, v 0.1 2015-10-18 下午1:04 admin Exp $$ */ public class Benz extends Car { public Benz() { super(); System.out.println("Product BenzBusiness!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.simpefactory; /** * @author admin * @version $Id Bmw.java, v 0.1 2015-10-18 下午1:03 admin Exp $$ */ public class Bmw extends Car { public Bmw() { super(); System.out.println("Product BmwBusiness!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.simpefactory; /** * @author admin * @version $Id CarFactory.java, v 0.1 2015-10-18 下午1:06 admin Exp $$ */ public class CarFactory { public static Car createCar(String type){ if (type.equals("AudiBusiness")){ return new Audi(); }else if (type.equals("BenzBusiness")){ return new Benz(); }else if (type.equals("BmwBusiness")){ return new Bmw(); } return null; } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.simpefactory; /** * @author admin * @version $Id Customer.java, v 0.1 2015-10-18 下午1:16 admin Exp $$ */ public class Customer { public static void main(String[] args) { //生产一个宝马 Car car = CarFactory.createCar("BmwBusiness"); if (car == null) { System.out.println("Procuct BmwBusiness failed!"); } //生产一个奥迪 Car car1 = CarFactory.createCar("AudiBusiness"); if (car1 == null) { System.out.println("Product AudiBusiness failed!"); } //生产一个奔驰 Car car2 = CarFactory.createCar("BenzBusiness"); if (car2 == null) { System.out.println("Product BenzBusiness failed!"); } //生产一个大众 Car car3 = CarFactory.createCar("dazhong"); if (car3 == null) { System.out.println("Product 大众 failed!"); } } }
运行结果:
Product BmwBusiness! Product AudiBusiness! Product BenzBusiness! Product 大众 failed!
(2)工厂模式
对于简单的工厂强依赖于用户输入,而且当增加了一个新的车辆种类时,对于工厂需要进行修改容易破坏原来的代码逻辑,不符合开闭原则。如下是工厂模式
每一种车型都已一种对应的工厂,当新增车型时只用扩展,不用修改就能够完成新的车型工厂生产。
/** * Open Free. * Code for Open Community, free to use! */ package designpattern.factorymethod; /** * @author admin * @version $Id Car.java, v 0.1 2015-10-18 下午1:02 admin Exp $$ */ public class Car { } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.factorymethod; /** * @author admin * @version $Id Audi.java, v 0.1 2015-10-18 下午1:06 admin Exp $$ */ public class Audi extends Car { public Audi() { System.out.println("Product AudiBusiness!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.factorymethod; /** * @author admin * @version $Id Benz.java, v 0.1 2015-10-18 下午1:04 admin Exp $$ */ public class Benz extends Car { public Benz() { super(); System.out.println("Product BenzBusiness!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.factorymethod; /** * @author admin * @version $Id Bmw.java, v 0.1 2015-10-18 下午1:03 admin Exp $$ */ public class Bmw extends Car { public Bmw() { super(); System.out.println("Product BmwBusiness!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.factorymethod; /** * @author admin * @version $Id CarFactory.java, v 0.1 2015-10-18 下午1:06 admin Exp $$ */ public interface CarFactory { public Car createCar(); } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.factorymethod; /** * @author admin * @version $Id AudiFactory.java, v 0.1 2015-10-18 下午1:35 admin Exp $$ */ public class AudiFactory implements CarFactory { @Override public Car createCar() { return new Audi(); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.factorymethod; /** * @author admin * @version $Id BenzFactory.java, v 0.1 2015-10-18 下午1:36 admin Exp $$ */ public class BenzFactory implements CarFactory { @Override public Car createCar() { return new Benz(); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.factorymethod; /** * @author admin * @version $Id BmwFactory.java, v 0.1 2015-10-18 下午1:36 admin Exp $$ */ public class BmwFactory implements CarFactory { @Override public Car createCar() { return new Bmw(); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.factorymethod; /** * @author admin * @version $Id Customer.java, v 0.1 2015-10-18 下午1:16 admin Exp $$ */ public class Customer { public static void main(String[] args) { //生产一个宝马 CarFactory carFactory = new BmwFactory(); Car car = carFactory.createCar(); if (car == null) { System.out.println("Procuct BmwBusiness failed!"); } //生产一个奥迪 carFactory = new AudiFactory(); Car car1 = carFactory.createCar(); if (car1 == null) { System.out.println("Product AudiBusiness failed!"); } //生产一个奔驰 carFactory = new BenzFactory(); Car car2 = carFactory.createCar(); if (car2 == null) { System.out.println("Product BenzBusiness failed!"); } } }
运行结果:
Product BmwBusiness! Product AudiBusiness! Product BenzBusiness!
(3)抽象工厂模式
抽象工厂使用的时候主要是业务比较复杂的时候才会考虑,比如当车的种类已经不仅仅是一个维度了,除了车的品牌,还要涉及到车的类型,如跑车、商务车等。此时车也要拆分到多个维度、跑车,商务车等。
/** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id BusinessCar.java, v 0.1 2015-10-18 下午2:00 admin Exp $$ */ public class BusinessCar { } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id SportsCar.java, v 0.1 2015-10-18 下午2:01 admin Exp $$ */ public class SportsCar { } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id AudiBusiness.java, v 0.1 2015-10-18 下午1:06 admin Exp $$ */ public class AudiBusiness extends BusinessCar { public AudiBusiness() { System.out.println("Product AudiBusiness!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id BenzBusiness.java, v 0.1 2015-10-18 下午1:04 admin Exp $$ */ public class BenzBusiness extends BusinessCar { public BenzBusiness() { super(); System.out.println("Product BenzBusiness!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id BmwBusiness.java, v 0.1 2015-10-18 下午1:03 admin Exp $$ */ public class BmwBusiness extends BusinessCar { public BmwBusiness() { super(); System.out.println("Product BmwBusiness!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id AudiBusiness.java, v 0.1 2015-10-18 下午1:06 admin Exp $$ */ public class AudiSports extends SportsCar { public AudiSports() { System.out.println("Product AudiSports!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id BenzSports.java, v 0.1 2015-10-18 下午1:04 admin Exp $$ */ public class BenzSports extends SportsCar { public BenzSports() { super(); System.out.println("Product BenzSports!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id BmwSports.java, v 0.1 2015-10-18 下午1:03 admin Exp $$ */ public class BmwSports extends SportsCar { public BmwSports() { super(); System.out.println("Product BmwSports!"); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id CarFactory.java, v 0.1 2015-10-18 下午1:06 admin Exp $$ */ public interface CarFactory { public SportsCar createSportsCar(); public BusinessCar createBusinessCar(); } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id AudiFactory.java, v 0.1 2015-10-18 下午2:15 admin Exp $$ */ public class AudiFactory implements CarFactory { @Override public SportsCar createSportsCar() { return new AudiSports(); } @Override public BusinessCar createBusinessCar() { return new AudiBusiness(); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id BenzFactory.java, v 0.1 2015-10-18 下午2:17 admin Exp $$ */ public class BenzFactory implements CarFactory { @Override public SportsCar createSportsCar() { return new BenzSports(); } @Override public BusinessCar createBusinessCar() { return new BenzBusiness(); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id BmwFactory.java, v 0.1 2015-10-18 下午2:18 admin Exp $$ */ public class BmwFactory implements CarFactory { @Override public SportsCar createSportsCar() { return new BmwSports(); } @Override public BusinessCar createBusinessCar() { return new BmwBusiness(); } } /** * Open Free. * Code for Open Community, free to use! */ package designpattern.abstractfactory; /** * @author admin * @version $Id Customer.java, v 0.1 2015-10-18 下午1:16 admin Exp $$ */ public class Customer { public static void main(String[] args) { /**生产宝马*/ CarFactory carFactory = new BmwFactory(); //跑车 SportsCar sportsCar = carFactory.createSportsCar(); //商务车 BusinessCar businessCar = carFactory.createBusinessCar(); /**生产奥迪*/ carFactory = new AudiFactory(); //跑车 sportsCar = carFactory.createSportsCar(); //商务车 businessCar = carFactory.createBusinessCar(); /**生产一个奔驰*/ carFactory = new BmwFactory(); //跑车 sportsCar = carFactory.createSportsCar(); //商务车 businessCar = carFactory.createBusinessCar(); } }
1.一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。
2.这个系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
3.同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。
4.系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。
分离接口和实现
客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已。也就是说,客户端从具体的产品实现中解耦。
posted on 2015-10-18 15:51 NewPanderKing 阅读(418) 评论(0) 编辑 收藏 举报