Android设计模式-抽象工厂模式

来源:互联网 发布:陈怡馨被迷 知乎 编辑:程序博客网 时间:2024/06/06 00:16

抽象工厂模式介绍

抽象工厂模式(Abstract Factory Pattern),也是创建型设计模式之一。大家联想一下,在现实生活中的工厂肯定都是具体的,也就是说每个工厂都会产生某一种具体的产品,也就是每一个工厂都会产生某种具体的产品,那么抽象工厂意味着生产出来的产品是不确定的。那这岂不是很奇怪?抽象工厂模式起源于以前对不同操作系统的图形化解决方案,如,不同操作系统中的按钮和文本框控件其实现不同,展示效果也不用,对于每一操作系统,其本身就构成一个产品类,而按钮与文本框控件也构成一个产品类,两种产品类两种变化,各有自己的特性,如Android中的Button和TextView,iOS中的Button和TextView,Windows Phone中的Button和TextView等。

抽象工厂模式的定义

为创建一组先关或者是相互依赖的对象提供一个接口,而不需要指定它们的具体类。

使用场景

当一个对象族有相同的约束时可以使用抽象工厂模式。举个栗子,Android,iOS,Windows Phone下都有短信软件和拨号软件,两者都属于Software软件的范畴,但它们所在的操作系统平台不一样,这时候就可以考虑使用抽象工厂方法模式来产生各个平台的短信和拨号软件。

抽象工厂模式的通用模板代码

//抽象产品类Apublic abstract class AbstractProductA {    //每个具体产品的子类需要实现的方法    public abstract void method();}//抽象产品类Bpublic abstract class AbstractProductB {    //每个具体产品的子类需要实现的方法    public abstract void method();}//具体产品类A1public class ConcreteProductA1 extends AbstractProductA {    @Override    public void method() {        System.out.println("具体产品A1的方法");    }}//具体产品类A2public class ConcreteProductA2 extends AbstractProductA {    @Override    public void method() {        System.out.println("具体产品A2的方法");    }}//具体产品类B1public class ConcreteProductB1 extends AbstractProductB {    @Override    public void method() {        System.out.println("具体产品B1的方法");    }}//具体产品类B2public class ConcreteProductB2 extends AbstractProductB {    @Override    public void method() {        System.out.println("具体产品B2的方法");    }}//抽象工厂类public abstract class AbstractFactory {    //创建产品A的方法    // @return 产品A的对象    public abstract AbstractProductA createProductA();    //创建产品B的方法    // @return 产品B的对象    public abstract AbstractProductB createProductB();}//具体工厂类1public class ConcreteFactory1 extends AbstractFactory {    @Override    public AbstractProductA createProductA() {        return new ConcreateProductA1();    }    @Override    public AbstractProductB createProductB() {        return new ConcreateProductB1();    }}//具体工厂类2public class ConcreteFactory2 extends AbstractFactory {    @Override    public AbstractProductA createProductA() {        return new ConcreateProductA2();    }    @Override    public AbstractProductB createProductB() {        return new ConcreateProductB2();    }}

虽然抽象工厂方法模式的类繁多,但是主要还是分为4类。

  • 抽象工厂类:AbstractFactory。它生命了一组用于创建一种产品的方法,每一方法对应一种产品,如上述模板汇总的AbstractFactory中就定义了两个方法,分别创建产品A和产品B。

  • 具体工厂类:ConcreteFactory。他实现了在抽此昂工厂中定义的创建产品的方法,生成一组具体产品,这些产品够长了一个产品种类,每一个产品都位于某个产品等级结构中,如上述类图中的ConcreteFactory1和ConcreteFactory2。

  • 抽象产品类:AbstractProduct。它为每种产品声明接口,比如上述类中的AbstractProductA和AbstractProductB。

  • 具体产品类:ConcreteProduct。它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法,如ConcreteProductA1、ConcreteProductA2、ConcreteProductB1、ConcreteProductB2。

抽象工厂方法的简单实现

在之前的一篇文章中使用了工厂方法模式,但是后来发现了一个问题,虽然Q3、Q5、Q7都是一个车系,但是三者之间的零部件差别却很大:比如Q3是国产发动机、Q7是进口的;Q3是普通轮胎、Q7是全尺寸的;Q3是普通制动系统、Q7是高性能的制动系统。。。等等。也就是说,Q3、Q7是一系列的车,而发动机、车胎、制动系统等零部件是不同类型,这时候就可以使用抽象工厂模式。首先,汽车工厂需要生产轮胎、发动机、制动系统这三种部件。

//抽象车厂类public abstract class CarFactory {    //生产轮胎    // @return 轮胎    public abstract ITitle createTire();    //生产发动机    // @return 发动机    public abstract IEngine createEngine();    //生产制动系统    // @return 制动系统    public abstract IBrake createBrake();}

这里我们为每一种零部件定义一个接口,并非额创建两个不同的实现类表示不同的零部件产品。

//轮胎相关类public interface ITitle {    //轮胎    void tire();}public class NormalTire implements ITire {    @Override    public void tire() {        System.out.println("普通轮胎");    }}  public class SUVTire implements ITire {    @Override    public void tire() {        System.out.println("越野轮胎");    }} //发动机相关类public interface IEngine {    //发动机    void engine();}public class DomesticEngine implements IEngine {    @Override    public void engine() {        System.out.println("国产发动机");    }}public class ImportEngine implements IEngine {    @Override    public void engine() {        System.out.println("进口发动机");    }}//制动系统相关类public interface IBrake {    //制动系统    void brake();}public class NormalBrake implements IBreake {    @Override    public void brake() {        System.out.println("不同制动");    }}public class SeniorBrake implements IBreake {    @Override    public void brake() {        System.out.println("高级制动");    }}

对于生产Q3的工厂,其使用的零部件不同,而生产Q7的工厂,其零部件也不同。

//Q3工厂类public class Q3Factory extends CarFactory {    @Override    public ITire createTire() {        return new NormalTire();    }    @Override    public IEngine createEngine() {        return new DomesticEngine();    }    @Override    public IBrake createBrake() {        return new NormalBrake();    }}
Q7工厂类public class Q7Factory extends CarFactory {    @Override    public ITire createTire() {        return new SUVTire();    }    @Override    public IEngine createEngine() {        return new ImportEngine();    }    @Override IBrake creeateBrake() {        return new SeniorBrake();    }}

最后,我们字啊一个Client客户类中模拟。

public class Client {    public static void main(String[] args) {        //构造一个生产Q3的工厂        CarFactory factoryQ3 = new Q3Factory();        factoryQ3.createTire().tire();        factoryQ3.createEngine().engine();        factoryQ3.createBrake().brake();        System.out.println("-----------------");        //构造一个生产Q7的工厂        CarFactory factoryQ7 = new Q3Factory();        factoryQ7.createTire().tire();        factoryQ7.createEngine().engine();        factoryQ7.createBrake().brake();    }}
//输出普通轮胎国产发动机普通制动-----------------越野轮胎进口发动机高级制动

总结

抽象工厂方法的优点:

分离接口与实现。客户端使用抽象工厂来创建需要的对象,而客户端跟就不知道、也无需知道是谁,客户端只需面向产品的接口编程,使其从具体的产品实现中解耦,同时基于接口与实现的分离,使抽象该工厂方法模式在切换产品类时更加灵活、容易。

抽象工厂方法的缺点:

(1)文件的爆炸性增长。

(2)不容易扩展新的产品类(如增加一个普通车灯与进口车灯),因为每增加一个产品类就需要修改抽象工厂,所有的具体工厂也需要修改。

0 0