设计模式之工厂模式(三)之抽象工厂模式

来源:互联网 发布:奇兵网络 编辑:程序博客网 时间:2024/06/01 09:24

设计模式之工厂模式(三)之抽象工厂模式

抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

定义

抽象工厂模式(Abstact Factory Pattern)是所有形态的工厂模式中最为抽象和最其一般
性的。抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的
情况下,能够创建多个产品族的产品对象。

UML图

抽象工厂模式模式中包含的角色及其相应的职责如下:
抽象工厂(Creator)角色:抽象工厂模式的核心,包含对多个产品结构的声明,任何工厂类都必须实现这个接口。
具体工厂(Concrete Creator)角色 : 具体工厂类是抽象工厂的一个实现,负责实例化某个产品族中的产品对象。
抽象(Product)产品角色:抽象模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
具体产品(ConcreteProduct)角色:抽象模式所创建的具体实例对象。

基本思想

抽象工厂模式是在当产品有多个 抽象角色的时候使用的一种创建型设计模式。按照里氏代换原则,凡是父类适用的地方,子类也必然适用。而在实际系统中 ,我们需要的是和父类类型相同的子类的实例对象,而不是父类本身,也就是这些抽象产品的具体子类的实例。具体工厂类就是来负责创建抽象产品的具体子类的实例的。
当每个抽象产品都有多于一个的具体子类的时候,工厂角色是如何确定实例化哪一个子类呢?例如说有两个抽象产品角色,而每个抽象产品角色都有两个具体产品 。
抽象工厂模式提供两个具体工厂角色,分别对应于这两个具体产品角色,每一个具体工厂角色只负责某一个产品角色的实例化。每一个具体工厂类只负责创建抽象产品的某一个具体子类的实例。
每一个模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是多个产品等级结构。
何谓产品族?产品族是指位于不同产品等级结构中,功能相关联的产品组成的家族。一般是位于不同的等级结构中的相同位置上。显然,每一个产品族中含有产品的数目,与产品等级结构的数目是相等的,形成一个二维的坐标系,水平坐标是产品等级结构,纵坐标是产品族。

代码实现

1、创建一个抽象产品的接口-形状

package com.zd.factory.staticmothed;public interface Shape {    void draw();}

2、创建实现抽象产品接口-形状的具体产品实体类

package com.zd.factory.staticmothed;public class Circle implements Shape{//实现抽象产品的接口    @Override    public void draw() {//获取产品        // TODO Auto-generated method stub        String str="我是一个圆形";        System.out.println(str);    }}
package com.zd.factory.staticmothed;public class Square implements Shape{    @Override    public void draw() {        // TODO Auto-generated method stub        String str="我是一个正方形";        System.out.println(str);    }}
package com.zd.factory.staticmothed;public class Rectangle implements Shape{    @Override    public void draw() {        // TODO Auto-generated method stub        String str="我是一个长方形";        System.out.println(str);    }}

3、创建一个抽象产品的接口-颜色

package com.zd.factory.staticmothed;/** * 创建一个抽象产品的接口-颜色 * @author Administrator * */public interface Colore {    void fillColore();}

4、创建实现抽象产品接口-颜色的具体产品实体类

package com.zd.factory.staticmothed;public class Blue implements Colore{    @Override    public void fillColore() {        // TODO Auto-generated method stub        String str="我会填充蓝色";        System.out.println(str);    }}
package com.zd.factory.staticmothed;public class Red implements Colore{    @Override    public void fillColore() {        // TODO Auto-generated method stub        String str="我会填充红色";        System.out.println(str);    }}
package com.zd.factory.staticmothed;public class Yellow implements Colore{    @Override    public void fillColore() {        // TODO Auto-generated method stub        String str="我会填充黄色";        System.out.println(str);    }}

5、 创建抽象类来获取工厂

package com.zd.factory.staticmothed;/** * 创建抽象类来获取工厂 * @author Administrator * */public abstract class AbstractFactory {     abstract Colore getColor(String color);    abstract Shape getShape(String shape);}

6、创建继承了抽象类工厂 (AbstractFactory) 的工厂类,基于给定的信息生成实体类的对象

package com.zd.factory.staticmothed;public class ColoreFactory extends AbstractFactory{    @Override    Colore getColor(String color) {        // TODO Auto-generated method stub        if (color == null) {            return null;        }        if (color.equalsIgnoreCase("red")) {            return new Red();        } else if (color.equalsIgnoreCase("blue")) {            return new Blue();        } else if ("YELLOW".equals(color)) {            return new Yellow();        }        return null;    }    @Override    Shape getShape(String shape) {        // TODO Auto-generated method stub        return null;    }}
package com.zd.factory.staticmothed;/** *  * @author Administrator * */public class ShapeFactory extends AbstractFactory{    @Override    Colore getColor(String color) {        // TODO Auto-generated method stub        return null;    }    @Override    Shape getShape(String shape) {        if (shape == null) {            return null;        }        if (shape.equalsIgnoreCase("CIRCLE")) {            return new Circle();        } else if (shape.equalsIgnoreCase("RECTANGLE")) {            return new Rectangle();        } else if ("square".equals(shape)) {            return new Square();        }        return null;    }}

7、建一个工厂创造器/生成器类,通过传递形状或颜色信息来获取工厂。

package com.zd.factory.staticmothed;public class FactoryProducer {public static AbstractFactory getAbstractFactory(String choice) {    if(choice.equalsIgnoreCase("SHAPE")){        return new ShapeFactory();     } else if(choice.equalsIgnoreCase("COLORE")){        return new ColoreFactory();     }     return null;}}

8、测试效果

我是一个圆形我是一个长方形我是一个正方形我会填充红色我会填充红色我会填充红色

优缺点分析

优点:客户端不再负责对象的具体创建,而是把这个责任交给了具体的工厂类,客户端之负责对对象的调用。当具有产品家族性质的产品被涉及到一个工厂类中后,对客户端而言是非常友好的,更重要的是如果想要更换为另外一产品家族,所要做的只是需要增加相应的产品家族成员和增加一个具体的产品工厂而已。
缺点:当有新的产品加入的时候,也就是当产品的结构发生改变时,修要修改抽象工厂类的设计,这就导致了必须修改所有的具体工厂类,导致很客观的工作量的增加。

实际应用

抽象工厂模式是针对多个产品系列的创建的问题,这在持久化层的设计很实现中有很大的指导意义。
1、由于 Java 的跨平台性,一般而言,持久化层都要考虑到都肿数据库的问题,例如 MySQL、Oracle 等,每一个数据库就相当于一个产品系列,持久化层必须设计好好不同产品系列的共同接口,这样才便于使用者操作数据库,同时也有利于数据库的移植。
2、 Hibernate 就借鉴了抽象工厂模式的设计方法。
3、QQ 换皮肤,一整套一起换。
4、生成不同操作系统的程序。

总结

抽象工厂模式考虑的是不同产品系列的创建的问题,并非能到处使用。另外在新增加产
品的时候,需要改变抽象工厂的设计,这会导致很大的工作量,所以在规划之初必须考虑好
产品的结构,力求降低参加产品的可能性,是抽象工厂比较稳定。
工厂方法模式和抽象工厂模式不好分清楚,他们的区别如下:
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例,也就是创建的是一个产品线下的多个产品。
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
工厂方法创建 “一种” 产品,他的着重点在于”怎么创建”,也就是说如果你开发,你的大量代码很可能围绕着这种产品的构造,初始化这些细节上面。也因为如此,类似的产品之间有很多可以复用的特征,所以会和模版方法相随。
抽象工厂需要创建一些列产品,着重点在于”创建哪些”产品上,也就是说,如果你开发,你的主要任务是划分不同差异的产品线,并且尽量保持每条产品线接口一致,从而可以从同一个抽象工厂继承。

感言

首先感谢尚硅谷无偿提供的学习资料。写博客是为了帮助开发者学习使用技术,同时巩固自己所学技术。如果此篇博客有助于您的学习,那是我的荣幸!如果此篇博客有任何瑕疵,请多多指教!在此感谢您的学习和指教!

原创粉丝点击