zoukankan      html  css  js  c++  java
  • 设计模式之抽象工程模式

    1.定义:提供一个创建一系列相关或相互依赖对象接口,而无需指定它们的实体类。

    2.引申:

    每个模式都是针对一定问题的解决方案。抽象工厂模式面对的问题是多产品等级结构的系统设计。
             在学习抽象工厂具体实例之前,应该明白两个重要的概念:产品族和产品等级。

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

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

    2.组成:

      抽象工厂:

      具体工厂:

      抽象产品:

      具体产品:

    3.UML类图:

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

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

    1. AbstractProduct: 抽象产品,它们都有可能有两种不同的实现。
    2. ConcreteProduct:包括ProductA和ProductB, 对两个抽象产品的具体分类的实现。
    3. AbstractFactory: 抽象工厂接口,它里面应该包含所有的产品创建的抽象方法。
    4. ConcreteFactory: 包括ConcreteFactoryA和ConcreteFactoryB,具体的工厂,创建具有特定实现的产品对象。

    4:示例:

    背景:用一个分别对不同数据库(Oracle 或 SQL Server)中表( User 和 Department )的操作的实例来展示该设计模式。先看下代码的结构图:

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

    IUser.java的源码:

    [html] view plaincopy
     
    1. package com.andyidea.patterns.abstractproduct;  
    2.   
    3. /**  
    4.  * 抽象产品角色:User接口  
    5.  * @author Andy.Chen  
    6.  *  
    7.  */  
    8. public interface IUser {  
    9.   
    10. }  

    IDepartment.java源码:

    [html] view plaincopy
     
    1. package com.andyidea.patterns.abstractproduct;  
    2.   
    3. /**  
    4.  * 抽象产品角色:Department接口  
    5.  * @author Andy.Chen  
    6.  *  
    7.  */  
    8. public interface IDepartment {  
    9.   
    10. }  

    3.2 定义抽象工厂类:IDBFactory.java

    [html] view plaincopy
     
    1. package com.andyidea.patterns.abstractfactory;  
    2.   
    3. import com.andyidea.patterns.abstractproduct.IDepartment;  
    4. import com.andyidea.patterns.abstractproduct.IUser;  
    5.   
    6. /**  
    7.  * 抽象工厂角色:工厂接口  
    8.  * @author Andy.Chen  
    9.  *  
    10.  */  
    11. public interface IDBFactory {  
    12.   
    13.     public IUser createUser();  
    14.     public IDepartment createDepartment();  
    15. }  

    3.3创建具体产品角色类:OracleOfUser.java;OracleOfDepartment.java;SQLServerOfUser.java;SQLServerOfDepartment.java。分别继承IUser.java和IDepartment.java。

    OracleOfUser.java源码:

    [html] view plaincopy
     
    1. package com.andyidea.patterns.concreteproduct;  
    2.   
    3. import com.andyidea.patterns.abstractproduct.IUser;  
    4.   
    5. /**  
    6.  * 具体产品角色:Oracle中的User  
    7.  * @author Andy.Chen  
    8.  *  
    9.  */  
    10. public class OracleOfUser implements IUser{  
    11.       
    12.     public OracleOfUser(){  
    13.         System.out.println("Oracle工厂:在Oracle中操作User表.");  
    14.     }  
    15.   
    16. }  

    OracleOfDepartment.java源码:

    [html] view plaincopy
     
    1. package com.andyidea.patterns.concreteproduct;  
    2.   
    3. import com.andyidea.patterns.abstractproduct.IDepartment;  
    4.   
    5. /**  
    6.  * 具体产品角色:Oracle中的Department  
    7.  * @author Andy.Chen  
    8.  *  
    9.  */  
    10. public class OracleOfDepartment implements IDepartment{  
    11.       
    12.     public OracleOfDepartment(){  
    13.         System.out.println("Oracle工厂:在Oracle中操作Department表.");  
    14.     }  
    15.   
    16. }  

    SQLServerOfUser.java源码:

    [html] view plaincopy
     
    1. package com.andyidea.patterns.concreteproduct;  
    2.   
    3. import com.andyidea.patterns.abstractproduct.IUser;  
    4.   
    5. /**  
    6.  * 具体产品角色:SQL Server中的User  
    7.  * @author Andy.Chen  
    8.  *  
    9.  */  
    10. public class SQLServerOfUser implements IUser{  
    11.       
    12.     public SQLServerOfUser(){  
    13.         System.out.println("SQL Server工厂:在SQL Server中操作User表.");  
    14.     }  
    15.   
    16. }  

    SQLServerOfDepartment.java源码:

    [html] view plaincopy
     
    1. package com.andyidea.patterns.concreteproduct;  
    2.   
    3. import com.andyidea.patterns.abstractproduct.IDepartment;  
    4.   
    5. /**  
    6.  * 具体产品角色:SQL Server中的Department  
    7.  * @author Andy.Chen  
    8.  *  
    9.  */  
    10. public class SQLServerOfDepartment implements IDepartment{  
    11.       
    12.     public SQLServerOfDepartment(){  
    13.         System.out.println("SQL Server工厂:在SQL Server中操作Department表.");  
    14.     }  
    15.   
    16. }  

    3.4 创建具体工厂类:OracleFactory.java和SQLServerFactory.java。

    OracleFactory.java源码:

    [html] view plaincopy
     
    1. package com.andyidea.patterns.concretefactory;  
    2.   
    3. import com.andyidea.patterns.abstractfactory.IDBFactory;  
    4. import com.andyidea.patterns.abstractproduct.IDepartment;  
    5. import com.andyidea.patterns.abstractproduct.IUser;  
    6. import com.andyidea.patterns.concreteproduct.OracleOfDepartment;  
    7. import com.andyidea.patterns.concreteproduct.OracleOfUser;  
    8.   
    9. /**  
    10.  * 具体工厂角色:Oracle工厂  
    11.  * @author Andy.Chen  
    12.  *  
    13.  */  
    14. public class OracleFactory implements IDBFactory{  
    15.   
    16.     @Override  
    17.     public IUser createUser() {  
    18.         return new OracleOfUser();  
    19.     }  
    20.   
    21.     @Override  
    22.     public IDepartment createDepartment() {  
    23.         return new OracleOfDepartment();  
    24.     }  
    25.   
    26. }  

    SQLServerFactory.java源码:

    [html] view plaincopy
     
    1. package com.andyidea.patterns.concretefactory;  
    2.   
    3. import com.andyidea.patterns.abstractfactory.IDBFactory;  
    4. import com.andyidea.patterns.abstractproduct.IDepartment;  
    5. import com.andyidea.patterns.abstractproduct.IUser;  
    6. import com.andyidea.patterns.concreteproduct.SQLServerOfDepartment;  
    7. import com.andyidea.patterns.concreteproduct.SQLServerOfUser;  
    8.   
    9. /**  
    10.  * 具体工厂角色:SQL Server工厂  
    11.  * @author Andy.Chen  
    12.  *  
    13.  */  
    14. public class SQLServerFactory implements IDBFactory{  
    15.   
    16.     @Override  
    17.     public IUser createUser() {  
    18.         return new SQLServerOfUser();  
    19.     }  
    20.   
    21.     @Override  
    22.     public IDepartment createDepartment() {  
    23.         return new SQLServerOfDepartment();  
    24.     }  
    25.   
    26. }  

    3.5 客户端测试类:AbstractFactoryClient.java

    [html] view plaincopy
     
    1. package com.andyidea.patterns.client;  
    2.   
    3. import com.andyidea.patterns.abstractproduct.IDepartment;  
    4. import com.andyidea.patterns.abstractproduct.IUser;  
    5. import com.andyidea.patterns.concretefactory.OracleFactory;  
    6. import com.andyidea.patterns.concretefactory.SQLServerFactory;  
    7.   
    8. /**  
    9.  * 抽象工厂测试类  
    10.  * @author Andy.Chen  
    11.  *  
    12.  */  
    13. public class AbstractFactoryClient {  
    14.   
    15.     public static void main(String[] args) {  
    16.           
    17.         System.out.println("Welcome to Andy.Chen Blog!" +" "   
    18.                    +"Abstract Factory Patterns." +" "  
    19.                    +"-------------------------------");  
    20.           
    21.         IUser oracleUser,sqlUser;  
    22.         IDepartment oracleDept,sqlDept;  
    23.         OracleFactory of = new OracleFactory();  
    24.         SQLServerFactory sf = new SQLServerFactory();  
    25.           
    26.         oracleUser = of.createUser();  
    27.         oracleDept = of.createDepartment();  
    28.         sqlUser = sf.createUser();  
    29.         sqlDept = sf.createDepartment();  
    30.     }  
    31. }  

    【4】程序运行结果:

    [html] view plaincopy
     
    1. Welcome to Andy.Chen Blog!  
    2. Abstract Factory Patterns.  
    3. -------------------------------  
    4. Oracle工厂:在Oracle中操作User表.  
    5. Oracle工厂:在Oracle中操作Department表.  
    6. SQL Server工厂:在SQL Server中操作User表.  
    7. SQL Server工厂:在SQL Server中操作Department表.  

    5.应用总结:

    抽象工厂模式优点:

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

    6.扩展:

      +反射+配置文件进一步满足OO的五大原则

  • 相关阅读:
    Python-05 基础语法-函数
    使用单个命令安装 WSL 现在可在 Windows 10 版本 2004 及更高版本中使用
    java.sql public interface ResultSet
    Selecting Contents for Uber JAR
    【初次使用h0遇到的一些问题】
    关于Swagger-UI下的渗透实战
    CTF—MISC—USB键盘流量分析
    k8s之路-Rancher
    单元测试
    flutter开发中设置模拟器一直悬浮在ide上方
  • 原文地址:https://www.cnblogs.com/myPersonalTailor/p/4941846.html
Copyright © 2011-2022 走看看