目录
简单工厂
简单工厂不是一种设计模式,反而比较像是一种编程习惯。简单工厂模式又叫做静态工厂方法模式(static Factory Method pattern),它是通过使用静态方法接收不同的参数来返回不同的实例对象
简单工厂包含如下角色:
抽象产品 :定义了产品的规范,描述了产品的主要特性和功能。
具体产品 :实现或者继承抽象产品的子类
具体工厂 :提供了创建产品的方法,调用者通过该方法来获取产品。
类图
抽象工厂模式实现
接口:抽象产品
public interface TestA { void test(); }实现类:具体产品
public class TestA1 implements TestA { @Override public void test() { System.out.println("测试A1"); } } public class TestA2 implements TestA { @Override public void test() { System.out.println("测试A2"); } }工厂类:具体工厂
public class TestFactory { public static TestA getInstance(Integer type){ TestA a = null; if(type == 1){ a = new TestA1(); } else if(type == 2){ a = new TestA2(); } return a; } }测试
public class Client { public static void main(String[] args) { TestA testa = TestFactory.getInstance(1); testa.test(); //输出:测试A1 } }总结:
优点:
封装了创建对象的过程,可以通过参数直接获取对象。把对象的创建和业务逻辑层分开,这样以后就避免了修改客户代码,如果要实现新产品直接修改工厂类,而不需要在原代码中修改,这样就降低了客户代码修改的可能性,更加容易扩展。
缺点:
增加新产品时还是需要修改工厂类的代码,违背了“开闭原则”。
工厂方法
概念: 定义一个用于创建对象的接口,让子类决定实例化哪个产品类对象。工厂方法使一个产品类的实例化延迟到其工厂的子类。
工厂方法模式的主要角色:
抽象工厂:提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品。
具体工厂:主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
抽象产品:定义了产品的规范,描述了产品的主要特性和功能。
具体产品:实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
类图
抽象工厂模式实现
抽象工厂
public interface AbstractFactory { TestA getInstance(); }具体工厂
public class SpecificFactoryA1 implements AbstractFactory{ @Override public TestA getInstance() { return new TestA1(); } } public class SpecificFactoryA2 implements AbstractFactory{ @Override public TestA getInstance() { return new TestA2(); } }测试
public class client { AbstractFactory factoryA1 = new SpecificFactoryA1(); AbstractFactory factoryA2 = new SpecificFactoryA2(); factoryA1.getInstance().test(); //测试A1 factoryA2.getInstance().test(); //测试A2 }总结:
优点:
用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;
在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;
缺点:
每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。
抽象工厂
抽象工厂模式比工厂方法模式的抽象程度更高. 在工厂方法模式中每一个具体工厂只需要生产一种具体产品,但是在抽象工厂模式中一个具体工厂可以生产一组相关的具体产品,这样一组产品被称为产品族.产品族中的每一个产品都分属于某一个产品继承等级结构。
产品等级结构与产品族
产品等级结构 :产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。
产品族 :在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中。
在上图中,每一个具体工厂可以生产属于一个产品族的所有产品,例如海尔工厂生产海尔电视机、海尔空调和海尔冰箱,所生产的产品又位于不同的产品等级结构中. 如果使用工厂方法模式,上图所示的结构需要提供9个具体工厂,而使用抽象工厂模式只需要提供3个具体工厂,极大减少了系统中类的个数.
抽象工厂模式概述
抽象工厂模式(Abstract Factory Pattern) 原始定义:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。
抽象工厂模式为创建一组对象提供了解决方案.与工厂方法模式相比,抽象工厂模式中的具体工厂不只是创建一种产品,而是负责创建一个产品族.如下图:
类图:
在抽象工厂模式中,每一个具体工厂都提供了多个工厂方法,用于产生多种不同类型的产品.这些产品构成了一个产品族.
抽象工厂模式的主要角色如下:
抽象工厂(Abstract Factory):它声明了一种用于创建一族产品的方法,每一个方法对应一种产品.
具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建.
抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它 同具体工厂之间是多对一的关系。
抽象工厂模式实现
抽象工厂:在一个抽象工厂中可以声明多个工厂方法,用于创建不同类型的产品
public interface AppliancesFactory { AbstractTV createTV(); AbstractFreezer createFreezer(); }具体工厂:每一个具体工厂方法,可以返回一个特定的产品对象,而同一个具体工厂所创建的产品对象构成了一个产品族.
public class HairFactory implements AppliancesFactory { @Override public AbstractTV createTV() { return new HairTV(); } @Override public AbstractFreezer createFreezer() { return new HairFreezer(); } } public class HisenseFactory implements AppliancesFactory { @Override public AbstractTV createTV() { return new HisenseTV(); } @Override public AbstractFreezer createFreezer() { return new HisenseFreezer(); } }抽象产品
public interface AbstractFreezer {} public interface AbstractTV {}具体产品
public class HairFreezer implements AbstractFreezer {} public class HisenseFreezer implements AbstractFreezer {} public class HairTV implements AbstractTV {} public class HisenseTV implements AbstractTV {}客户端
public class Client { private AbstractTV tv; private AbstractFreezer freezer; public Client(AppliancesFactory factory){ //在客户端看来就是使用抽象工厂来生产家电 this.tv = factory.createTV(); this.freezer = factory.createFreezer(); } public AbstractTV getTv() { return tv; } public void setTv(AbstractTV tv) { this.tv = tv; } public AbstractFreezer getFreezer() { return freezer; } public void setFreezer(AbstractFreezer freezer) { this.freezer = freezer; } public static void main(String[] args) { Client client = new Client(new HisenseFactory()); AbstractTV tv = client.getTv(); System.out.println(tv); AbstractFreezer freezer = client.getFreezer(); System.out.println(freezer); } }总结
从上面代码实现中我们可以看出,抽象工厂模式向使用(客户)方隐藏了下列变化:
程序所支持的实例集合(具体工厂)的数目;
当前是使用的实例集合中的哪一个实例;
在任意给定时刻被实例化的具体类型;
所以说,在理解抽象工厂模式原理时,你一定要牢牢记住“如何找到某一个类产品的正确共性功能”这个重点。
优点
对于不同产品系列有比较多共性特征时,可以使用抽象工厂模式,有助于提升组件的复用性.
当需要提升代码的扩展性并降低维护成本时,把对象的创建和使用过程分开,能有效地将代码统一到一个级别上
解决跨平台带来的兼容性问题
缺点
增加新的产品等级结构麻烦,需要对原有结构进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大不变,违背了开闭原则.