学习设计模式之二:抽象工厂模式(Abstract Factory)

学习设计模式之二:抽象工厂模式(Abstract Factory),第1张

概述  每个模式都是针对一定问题的解决方案。抽象工厂模式面对的问题是多产品等级结构的系统设计。          在学习抽象工厂具体实例之前,应该明白两个重要的概念:产品族和产品等级。          产品族:是指位于不同产品等级结构中,功能相关联的产品组成的家族。比如AMD的CPU和ADM芯片的主板,组成一个家族。Intel的CPU和Intel芯片的主板,又组成一个家族。而这两个家族都来自于两个产   每个模式都是针对一定问题的解决方案。抽象工厂模式面对的问题是多产品等级结构的系统设计。
         在学习抽象工厂具体实例之前,应该明白两个重要的概念:产品族和产品等级。

         产品族:是指位于不同产品等级结构中,功能相关联的产品组成的家族。比如AMD的cpu和ADM芯片的主板,组成一个家族。Intel的cpu和Intel芯片的主板,又组成一个家族。而这两个家族都来自于两个产品等级:cpu,主板。一个等级结构是由相同的结构的产品组成,示意图如下:


 理解这个产品结构是理解抽象工厂模式的关键所在,从上图可以看出,抽象工厂模式的每个工厂创造出来的都是一族产品,而不是一个或者一组。组是可以随意组合的!其实工厂方法模式和抽象工厂模式就这点点差别。

【1】基本概念

         抽象工厂模式是提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体类。

【2】简单分析

我们先看一下抽象工厂模式的UML结构图:

上图是 Abstract Factory 模式结构图,让我们可以进行更加方便的描述:

AbstractProduct: 抽象产品,它们都有可能有两种不同的实现。 ConcreteProduct:包括ProductA和ProductB, 对两个抽象产品的具体分类的实现。 AbstractFactory: 抽象工厂接口,它里面应该包含所有的产品创建的抽象方法。 ConcreteFactory: 包括ConcreteFactoryA和ConcreteFactoryB,具体的工厂,创建具有特定实现的产品对象。 【3】 如何用java语言来实现该模式
背景:用一个分别对不同数据库(Oracle 或 sql Server)中表( User 和 Department )的 *** 作的实例来展示该设计模式。先看下代码的结构图:


3.1 首先定义两个抽象的产品类:IUser.java 和 IDepartment.java。

IUser.java的源码:

[HTML]  view plain copy package com.andyIDea.patterns.abstractproduct;      /**    * 抽象产品角色:User接口    * @author Andy.Chen    *    */   public interface IUser {      }   IDepartment.java源码:

copy  * 抽象产品角色:Department接口    */   public interface IDepartment {      }   3.2 定义抽象工厂类:IDBFactory.java

copy @H_403_176@package com.andyIDea.patterns.abstractfactory;   import com.andyIDea.patterns.abstractproduct.IDepartment;   import com.andyIDea.patterns.abstractproduct.IUser;   /**    * 抽象工厂角色:工厂接口    * @author Andy.Chen    *    */   public interface IDBFactory {       public IUser createuser();       public IDepartment createDepartment();   }   3.3创建具体产品角色类:OracleOfUser.java;OracleOfDepartment.java;sqlServerOfUser.java;sqlServerOfDepartment.java。分别继承IUser.java和IDepartment.java。

OracleOfUser.java源码:

copy @H_403_176@package com.andyIDea.patterns.concreteproduct;   import com.andyIDea.patterns.abstractproduct.IUser;    * 具体产品角色:Oracle中的User   public class OracleOfUser implements IUser{              public OracleOfUser(){           System.out.println("Oracle工厂:在Oracle中 *** 作User表.");       }   }   OracleOfDepartment.java源码:

copy import com.andyIDea.patterns.abstractproduct.IDepartment;    * 具体产品角色:Oracle中的Department   public class OracleOfDepartment implements IDepartment{       public OracleOfDepartment(){           System.out.println("Oracle工厂:在Oracle中 *** 作Department表.");   }   sqlServerOfUser.java源码:

copy package com.andyIDea.patterns.concreteproduct;       * 具体产品角色:sql Server中的User   public class sqlServerOfUser implements IUser{       public sqlServerOfUser(){           System.out.println("sql Server工厂:在sql Server中 *** 作User表.");   }   sqlServerOfDepartment.java源码:

copy  * 具体产品角色:sql Server中的Department   public class sqlServerOfDepartment implements IDepartment{       public sqlServerOfDepartment(){           System.out.println("sql Server工厂:在sql Server中 *** 作Department表.");   }   3.4 创建具体工厂类:OracleFactory.java和sqlServerFactory.java。

OracleFactory.java源码:

copy @H_403_176@package com.andyIDea.patterns.concretefactory;   import com.andyIDea.patterns.abstractfactory.IDBFactory;   import com.andyIDea.patterns.abstractproduct.IDepartment;   import com.andyIDea.patterns.abstractproduct.IUser;   import com.andyIDea.patterns.concreteproduct.OracleOfDepartment;   import com.andyIDea.patterns.concreteproduct.OracleOfUser;    * 具体工厂角色:Oracle工厂   public class OracleFactory implements IDBFactory{       @OverrIDe       public IUser createuser() {           return new OracleOfUser();       }       @OverrIDe       public IDepartment createDepartment() {           return new OracleOfDepartment();   }   sqlServerFactory.java源码:

copy package com.andyIDea.patterns.concretefactory;   import com.andyIDea.patterns.concreteproduct.sqlServerOfDepartment;   import com.andyIDea.patterns.concreteproduct.sqlServerOfUser;    * 具体工厂角色:sql Server工厂    *   public class sqlServerFactory implements IDBFactory{           return new sqlServerOfUser();       public IDepartment createDepartment() {           return new sqlServerOfDepartment();       }   }   3.5 客户端测试类:AbstractFactoryClIEnt.java

copy @H_403_176@package com.andyIDea.patterns.clIEnt;   import com.andyIDea.patterns.abstractproduct.IDepartment;   import com.andyIDea.patterns.abstractproduct.IUser;   import com.andyIDea.patterns.concretefactory.OracleFactory;   import com.andyIDea.patterns.concretefactory.sqlServerFactory;   /**    * 抽象工厂测试类    *    */   public class AbstractFactoryClIEnt {       public static voID main(String[] args) {                      System.out.println("Welcome to Andy.Chen Blog!" +"\n"                       +"Abstract Factory Patterns." +"\n"                      +"-------------------------------");           IUser oracleUser,sqlUser;           IDepartment oracleDept,sqlDept;           OracleFactory of@H_403_176@ = new@H_403_176@ OracleFactory();           sqlServerFactory sf@H_403_176@ = new@H_403_176@ sqlServerFactory();                      oracleUser@H_403_176@ = of@[email protected]();           oracleDept@H_403_176@ = of@[email protected]();           sqlUser@H_403_176@ = sf@[email protected]();           sqlDept@H_403_176@ = sf@[email protected]();   }   【4】程序运行结果:

copy @H_403_176@Welcome to Andy.Chen Blog!   Abstract Factory Patterns.   -------------------------------   Oracle工厂:在Oracle中 *** 作User表.   Oracle工厂:在Oracle中 *** 作Department表.   sql Server工厂:在sql Server中 *** 作User表.   sql Server工厂:在sql Server中 *** 作Department表.   【5】总结

抽象工厂模式优点:

第一,易于交换产品系列,由于具体工厂类,例如IDBFactory factory = new OracleFactory(),在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它之需要改变具体工厂即可使用不同的产品配置。
第二,它让具体的创建实例与客户端分离,客户端是通过它们的抽象接口 *** 纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户端代码中。

转自:http://www.voidcn.com/article/p-mcofosod-ey.html

总结

以上是内存溢出为你收集整理的学习设计模式之二:抽象工厂模式(Abstract Factory)全部内容,希望文章能够帮你解决学习设计模式之二:抽象工厂模式(Abstract Factory)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/sjk/1178102.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存