首页 > 代码库 > 设计模式之工厂模式
设计模式之工厂模式
一、简单工厂模式
public interface Car { public void drive();}
public class Benz implements Car { public void drive() { System.out.println("Driving Benz"); }}
public class Bmw implements Car { public void drive() { System.out.println("Driving Bmw"); }}
public class CarFactory { /*** * 简单工厂,告诉我产品的名字,我就能给你生成相应的产品 * @param carName * @return */ public static Car createCar(String carName){ if(carName.equals("Benz")){ return new Benz(); }else if(carName.equals("Bmw")){ return new Bmw(); } return null; }}
public class Person { public static void main(String[] args) { Car car = CarFactory.createCar("Bmw"); car.drive(); }}
OK,现在可以对上面的代码解释了,奔驰和宝马都是汽车的一种,所以它们都实现了Car接口,如果我需要在Person类中要使用Benz车,常规的做法是直接Car car = new Benz();,这样做不好的地方是造成了Person和Benz的耦合。解决这个问题的办法如上,我创建一个制造汽车的工厂,我这个工厂什么车都能做,也就是将new产品的过程交给工厂处理,在Person中只要告诉工厂要造哪种车,工厂内部会将我要的车new好并返回给我。涉及到的几个角色如下:
1、工厂类角色(CarFactory):这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现。
2、抽象产品角色(Car):它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。
3、具体产品角色(Benz、Bmw):工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
二、工厂方法模式
public interface ICarFactory { Car createCar();}
public class BmwFactory implements ICarFactory { public Car createCar() { return new Bmw(); }}
public class BenzFactory implements ICarFactory { public Car createCar() { return new Benz(); }}
public class Person { public static void main(String[] args) { ICarFactory factory = new BmwFactory(); Car car = factory.createCar(); car.drive(); }}
对于简单工厂模式来说,每增加一种品牌的车,都要在工厂类中增加相应的逻辑判断,这就违背了开闭原则,也因此有了工厂方法模式。工厂方法模式将工厂先抽象出来,当需要一种品牌的车时创建对应的具体工厂,具体的工厂负责new出具体的车,这样在Person中需要用车的时候,直接创建一个对应的工厂就行了,不用关心也看不到具体的车是怎么new出来的,能拿到想要的车就对了。涉及到的几个角色如下:
1、抽象工厂角色(ICarFactory):这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
2、具体工厂角色(BenzFactory、BmwFactory):它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。
3、抽象产品角色(Car):它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
4、具体产品角色(Bmw、Benz):具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
三、抽象工厂模式
抽象工厂模式是三类工厂模式中使用最广泛的,也是最难理解的,所以先做简单解释再上代码。抽象工厂模式主要用于解决一系列相互依赖的对象 或者 有组合关系的对象的创建过程。怎么说呢,这个就像汽车各部件之间的关系,一个方向盘对应四个轮子,它们之间有一定的数量依赖关系,我们制造零件的时候要按照比例来进行就可以了,最简单的办法就是让它们在同一个抽象工厂中制造。此处代码就不上了,应该能想象到,这就形成了最典型的抽象工厂,但这并不是我们常用的,因为它还不够灵活。下面介绍常用的抽象工厂模式的实现方案:
通过配置文件实现
通过工厂初始化时从配置文件中读取配置项,构造一个字典,然后从这个字典中查询要创建的类型是否在字典中,如果在字典中存在则创建这个类型的对象,否则返回NULL,我们这里通过泛型来实现。那么如果我们想实现支持多个具有依赖关系或者组合关系的不同的创建形式的通用创建工厂时,我们如何来做呢?同上面的思路,只不过我们外部需要再添加一个字典,负责类型和抽象工厂的映射,即抽象工厂可以创建的字典列表及抽象工厂具体实例类型之间的键值对关系,或者通过配置文件来组织父子级的关系。
public interface IAbstractFactory{ T Create<T>();}
public class AbstractFactory : IAbstractFactory{ /// <summary> /// 工厂与工厂能够创建的对象类型字典之间的映射字典 /// </summary> private static readonly IDictionary<Type, Dictionary<Type, Type>> typeMapper = null; private Type factoryType = null; public static AbstractFactory() { //从具体的配置项中读取,从配置文件中读取或者通过某个方法来硬编码实现等。 //这里推荐的做法是从配置文件中读取。 //根据配置文件中的ObjectInstance 节点放在对应的工厂下的字典中 //每个工厂节点FactorySection 就会创建一个字典,并且将这个工厂能够创建的类型放在这个字典中 typeMapper = new Dictionary<Type, Dictionary<Type, Type>>(); } public AbstractFactory(string typeName) { this.factoryType = Type.GetType(typeName); } public T Create<T>() { if(typeMapper.ContainsKey(this.factoryType)) return default(T); Dictionary<Type, Type> instances = typeMapper[this.factoryType]; if (!instances.ContainsKey(typeof(T))) return default(T); Type typeInstance = instances[typeof(T)]; T obj = (T)Activator.CreateInstance(typeInstance); return obj; }}
<?xml version="1.0" encoding="utf-8" ?><AbstractFactory> <FactorySections> <FactorySection name="ProductFactory" type="DesignPattern.ProductFactory"> <ObjectInstance name="" type=""/> <ObjectInstance name="" type=""/> <ObjectInstance name="" type=""/> <ObjectInstance name="" type=""/> </FactorySection> <FactorySection name="FoodFactory" type="DesignPattern.FoodFactory"> <ObjectInstance name="" type=""/> <ObjectInstance name="" type=""/> <ObjectInstance name="" type=""/> <ObjectInstance name="" type=""/> </FactorySection> <FactorySection name="BookFactory" type="DesignPattern.BookFactory"> <ObjectInstance name="" type=""/> <ObjectInstance name="" type=""/> <ObjectInstance name="" type=""/> <ObjectInstance name="" type=""/> </FactorySection> </FactorySections></AbstractFactory>
总结
通过上面的实现方式和思路,我们来对比一下抽象工厂、工厂模式、简单工厂模式之间的差异和相同点。
相同点:
1、都是为客户调用程序与具体的对象类型之间提供了一个解耦作用,这里怎么说呢?其实就是应用程序不关心这个对象是怎么出来的,只关系如何使用这个对象,而且以后就算对象发生变化,那么也不需要修改用户应用程序的代码。
2、提高了程序的可维护性和低耦合性。
异同点:
1、简单工厂模式:是简单的一些列没有任何依赖关系的对象的创建,内部包含复杂的逻辑关系,一半是通过配置或者参数来进行创建对象,适合对象类型不多,并且不会经常新增的情况下。
工厂模式:每个工厂负责具体类型对象的创建,提供了可以动态新增产品类型的创建,并不需要修改现有的程序就可以无缝的新增产品类型。
抽象工厂模式:支持动态的新增对象类型和新增工厂类型,实现多种依赖关系的对象或者组合关系的创建,适合现有项目中的对象创建过程。
2、简单工厂模式:内部逻辑复杂,不符合高内聚的原则。
工厂模式:每次新增一个对象类型,就必须新增一个对应的创建工厂,无疑这是一个非常大的工作量。
抽象工厂模式:是在简单工厂模式的基础上经过改进具有前2个模式的优点,又屏蔽了他们的一些缺点。
当然我们在具体的项目中,还是需要具体的情况具体分析,一般情况下,我们对于这种数据库平滑迁移时,简单工厂可能比其他2类工厂更容易做,也很灵活。
设计模式之工厂模式