1. 写在前面
网上关于设计模式的文章已经非常详尽了,写这篇文章旨在给自己的学习做一个笔记和总结方便以后翻阅查找,若对你有用可细学之若觉得肤浅可略之。
工厂模式属于创建型设计模式,分为简单工厂模式,工厂方法模式,抽象工厂模式三种,话不多说,请看下面一一道来。
2. 简单工厂模式
简单工厂模式属于创建型设计模式,又叫静态工厂(Static Factory Method)模式,简单工厂模式(静态工厂模式)是工厂内部根据传入的条件(或者工厂内部决定)创建出适合的产品,简单工厂模式相对来说是工厂模式中最简单的一种设计模式(相对于工厂方法模式和抽象工厂模式)。
2.1 UML类图
从UML类图中可以看出简单工厂存在几种不同的角色,一是产品的父类即产品模版IProduct,二是继承IProduct的不同产品ProductA,ProductB...,三是最重要的负责生产产品的Factory工厂类,当然还包括一个模拟的Client。Client端只需要通过Factory就可以根据不同的需求创建出不同的Product,而不需要直接通过new来创建,这样就屏蔽了对象的创建过程。
2.2 代码示例
抽象产品接口类:
public interface IProduct {
public void create(String s);
}
具体产品实现类:
public class ProductA implements IProduct{
public ProductA() {
}
@Override
public void create(String s) {
// TODO Auto-generated method stub
System.out.println("ProductA create");
}
}
public class ProductB implements IProduct{
public ProductB() {
}
@Override
public void create(String s) {
// TODO Auto-generated method stub
System.out.println("ProductB create");
}
}
工厂类:
public class Factory {
public static <T extends IProduct> T createProduct(int flag) {
T product = null;
switch (flag) {
case 1:
product = (T)new ProductA();
break;
case 2:
product = (T)new ProductB();
break;
default:
product = (T)new ProductA();
break;
}
return product;
}
}
简单客户端测试类:
public class Client {
public static void main(String[] args) {
Factory.createProduct(1).create("test");
}
}
2.3 在源码中的实际应用
BitmapFactory->res.openRawResource->mResourcesImpl.openRawResource->getValue->mAssets.getResourceValue
3. 工厂方法模式
工厂方法模式(Factory Method)又叫多态工厂模式和虚拟构造器模式,通过定义工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象。
3.1 UML类图
从UML图中可以看出工厂方法模式和简单工厂模式比较类似或者说工厂方法模式是对简单工厂模式的扩展,仍然是利用工厂根据不同的需求创建不同的产品,创建过程在UML图中没有体现(和简单工厂类似),工厂方法模式中重点在方法两个字上,这里附上自己对其的理解-所谓方法即在父类或接口(产品共性)中定义abstract方法或者接口方法,在具体的产品中实现方法,这样我们可以通过父类或者接口的定义但在内存中指向的是具体的实现来调用具体产品的实现。(呵呵,不知道说得清楚不清楚,反正我是这样理解的)
3.2 代码示例
抽象产品类:
public interface IProduct {
public void show();
}
具体产品A:
public class ProductA implements IProduct {
@Override
public void show() {
// TODO Auto-generated method stub
System.out.println("ProductA show()");
}
}
具体产品B:
public class ProductB implements IProduct {
@Override
public void show() {
// TODO Auto-generated method stub
System.out.println("ProductB show()");
}
}
抽象构造器(定义抽象方法或接口方法的父类,主要体现工厂方法中方法二字的父类):
public abstract class Creator {
public abstract IProduct factoryMethod();
public void operate() {
IProduct product = factoryMethod();
product.show();
}
}
具体构造器A:
public class ConcreteCreatorA extends Creator {
public IProduct factoryMethod(){
return new ProductA();
}
}
具体构造器B:
public class ConcreteCreatorB extends Creator {
public IProduct factoryMethod(){
return new ProductB();
}
}
public class ConcreteCreatorB extends Creator {
public IProduct factoryMethod(){
return new ProductB();
}
}
最后工厂类及测试类:
public class Factory {
public static Creator generateCreator(int flag) {
Creator creator = null;
switch (flag) {
case 1:
creator = new ConcreteCreatorA();
break;
case 2:
creator = new ConcreteCreatorB();
break;
default:
creator = new ConcreteCreatorA();
break;
}
return creator;
}
}
public class Client {
public static void main(String[] args) {
Factory.generateCreator(2).operate();
}
}
3.3 在源码中的应用体现
工 厂方法模式在Android中应用如:
List(抽象工厂方法)->AbstractList->ArrayList(具体工厂方法实现,实际会调用里面的实现)
Activity(工厂,工厂方法)->ListActivity(具体工厂方法实现和具体产品)
LayoutInflater.FactoryManager->LayoutInflater.Factory(Factory2)(工厂方法)->Activity(或者具体的Activity)(具体工厂方法实现和具体产品)
4. 抽象工厂模式
引用百度百科的抽象工厂模式的定义-为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类;抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象,这里有引入了一个产品族的概念-所谓产品族就是具有相同功能(实现同一接口或abstract class)的不同对象。
4.1 UML类图
从UML图中可以看出抽象工厂模式有以下几种角色存在:
抽象工厂(Abstract Factory)角色:担任这个角色的是工厂方法模式的核心, 定义生产不同产品族的方法,通常为interface或者abstract class;对应UML图中的AbstractFactory类。
具体工厂(Concrete Factory)角色:这个角色直接在客户端的调用下创建产品的实例,即创建不同产品族中合适的产品,其implements或者extends AbstractFactory;对应UML图中的ConcreteFactory1和ConcreteFactory2。
抽象产品(Abstract Product)角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口;对应UML图中的AbstractProductA和AbstractProductB。
具体产品(Concrete Product)角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。是最终需要的东西;对应UML图中的ProductA1,ProcuctB1,ProductA2,ProductB2。
4.2 代码示例
AbstractFactory:
public abstract class AbstractFactory {
public abstract AbstractProductA createProductA();
public abstract AbstractProductB createProductB();
}
ConcreteFactory1:
public class ConcreteFactory1 extends AbstractFactory {
@Override
public AbstractProductA createProductA() {
return new ProductA1();
}
@Override
public AbstractProductB createProductB() {
return new ProductB1();
}
}
ConcreteFactory2:
public class ConcreteFactory2 extends AbstractFactory {
@Override
public AbstractProductA createProductA() {
return new ProductA2();
}
@Override
public AbstractProductB createProductB() {
return new ProductB2();
}
}
AbstractProductA:
public interface AbstractProductA {
public void show();
}
AbstractProductB:
public interface AbstractProductB {
public void show();
}
ProductA1:
public class ProductA1 implements AbstractProductA {
@Override
public void show() {
System.out.println("ProductA1");
}
}
ProductA2:
public class ProductA2 implements AbstractProductA {
@Override
public void show() {
System.out.println("ProductA2");
}
}
ProductB1:
public class ProductB1 implements AbstractProductB {
@Override
public void show() {
System.out.println("ProductB1");
}
}
ProductB2:
public class ProductB2 implements AbstractProductB {
@Override
public void show() {
System.out.println("ProductB2");
}
}
Client:
public class Client {
public static void main(String[] args) {
new ConcreteFactory1().createProductA().show();
new ConcreteFactory1().createProductB().show();
new ConcreteFactory2().createProductA().show();
new ConcreteFactory2().createProductB().show();
}
}
4.3 在源码中的应用体现
写过JDBC连接数据库的应该知道,JDBC中Connection是通过Driver及对应的URL过创建的,其实在这个创建过程中就用到了抽象工厂模式。
5. 为什么要使用工厂模式
其实设计模式就是为了解决某一特定的问题或者说更方便的解决问题而出现的,那使用它到底有什么好处呢:
简单工厂:这个比较好理解,封装解耦,客户端不用关心具体的实现类,只需要知道其父类就可以了;当然也有一些弊端,不利于扩展,当需要增加产品的时候就需要额外增加工厂类来实现。
工厂方法:同样,隔离了对象的创建过程,降低耦合,感觉是对简单工厂的进一步扩充。
抽象工厂:同简单工厂和工厂方法一样,隔离了对象的创建过程,降低耦合;并可以保证同一个工厂中创建出来的是同一个产品族中的产品;便于扩充,扩充时不需要修改原来的代码结构;但其代码结构比较复杂不好理解,在新增产品时需要修改AbstractFactory进行扩展。
好了,关于工厂模式(简单工厂,工厂方法,抽象工厂)就说到了这里,纯属个人理解和学习笔记。