zoukankan      html  css  js  c++  java
  • 创建类型5-2:抽象工厂模式(Abstract Factory Pattern)

    1. 概述

    抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

    在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

    2. 介绍

    2.1 意图

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

    2.2 主要解决

    主要解决接口选择的问题。

    2.3 何时使用

    系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。

    2.4 如何解决

    在一个产品族里面,定义多个产品。

    关键代码:

    在一个工厂里聚合多个同类产品。

    2.5 应用实例

    工作了,为了参加一些聚会,肯定有两套或多套衣服吧,比如说有商务装(成套,一系列具体产品)、时尚装(成套,一系列具体产品),甚至对于一个家庭来说,可能有商务女装、商务男装、时尚女装、时尚男装,这些也都是成套的,即一系列具体产品。假设一种情况(现实中是不存在的,要不然,没法进入共产主义了,但有利于说明抽象工厂模式),在您的家中,某一个衣柜(具体工厂)只能存放某一种这样的衣服(成套,一系列具体产品),每次拿这种成套的衣服时也自然要从这个衣柜中取出了。用 OO 的思想去理解,所有的衣柜(具体工厂)都是衣柜类的(抽象工厂)某一个,而每一件成套的衣服又包括具体的上衣(某一具体产品),裤子(某一具体产品),这些具体的上衣其实也都是上衣(抽象产品),具体的裤子也都是裤子(另一个抽象产品)。

    2.6 优点

    当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

    2.7 缺点

    产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。

    2.8 使用场景

    1、QQ 换皮肤,一整套一起换。 2、生成不同操作系统的程序。

    2.9 注意事项

    产品族难扩展,产品等级易扩展。

    3. 参与者

    1.AbstractProduct (interface)
    	为一类产品对象声明一个接口。
    	
    2.ConcreteProduct
    	定义一个将被相应的具体工厂创建的产品对象。
    	实现AbstractProduct接口。
    	
    3.AbstractFactory(interface)
    	声明一个创建抽象工厂对象的操作接口。
    
    4.ConcreteFactory
    	实现创建具体工厂对象的操作。
    	
    5.ConcreteSupperFactory
    构建一个超级工厂,包含了所有工厂对象。
    

    4. 类图

    我们将创建 ShapeColor 接口和实现这些接口的实体类。下一步是创建抽象工厂类 AbstractFactory。接着定义工厂类 ShapeFactoryColorFactory,这两个工厂类都是扩展了 AbstractFactory。然后创建一个工厂创造器/生成器类 FactoryProducer

    AbstractFactoryPatternDemo,我们的演示类使用 FactoryProducer 来获取 AbstractFactory 对象。它将向 AbstractFactory 传递形状信息 ShapeCIRCLE / RECTANGLE / SQUARE),以便获取它所需对象的类型。同时它还向 AbstractFactory 传递颜色信息 ColorRED / GREEN / BLUE),以便获取它所需对象的类型。

    image-20190518100201174

    5. 例子

    5.1 AbstractProduct && ConcreteProduct

    public interface Shape {
       void draw();
    }
    
    //ConcreteProduct
    class Rectangle implements Shape {
     
       @Override
       public void draw() {
          System.out.println("Inside Rectangle::draw() method.");
       }
    }
    
    class Square implements Shape {
     
       @Override
       public void draw() {
          System.out.println("Inside Square::draw() method.");
       }
    }
    
    public interface Color {
       void fill();
    }
    
    //ConcreteProduct
    class Red implements Color {
     
       @Override
       public void fill() {
          System.out.println("Inside Red::fill() method.");
       }
    }
    
    class Green implements Color {
     
       @Override
       public void fill() {
          System.out.println("Inside Green::fill() method.");
       }
    }
    

    AbstractFactory && ConcreteFactory

    public abstract class AbstractFactory {
       public abstract Color getColor(String color);
       public abstract Shape getShape(String shape) ;
    }
    
    //ConcreteFactory
    class ShapeFactory extends AbstractFactory {
        
       @Override
       public Shape getShape(String shapeType){
          if(shapeType == null){
             return null;
          }        
          if(shapeType.equalsIgnoreCase("RECTANGLE")){
             return new Rectangle();
          } else if(shapeType.equalsIgnoreCase("SQUARE")){
             return new Square();
          }
          return null;
       }
       
       @Override
       public Color getColor(String color) {
          return null;
       }
    }
    
    class ColorFactory extends AbstractFactory {
        
       @Override
       public Shape getShape(String shapeType){
          return null;
       }
       
       @Override
       public Color getColor(String color) {
          if(color == null){
             return null;
          }        
          if(color.equalsIgnoreCase("RED")){
             return new Red();
          } else if(color.equalsIgnoreCase("GREEN")){
             return new Green();
          }
          return null;
       }
    }
    

    ConcreteSupperFactory

    public class FactoryProducer {
       public static AbstractFactory getFactory(String choice){
          if(choice.equalsIgnoreCase("SHAPE")){
             return new ShapeFactory();
          } else if(choice.equalsIgnoreCase("COLOR")){
             return new ColorFactory();
          }
          return null;
       }
    }
    

    test

    public class AbstractFactoryPatternDemo {
       public static void main(String[] args) {
          //获取形状工厂
          AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
          //获取形状为 Rectangle 的对象,调用 Rectangle 的 draw 方法
          Shape shape1 = shapeFactory.getShape("RECTANGLE");
          shape1.draw();
          //获取形状为 Square 的对象,调用 Square 的 draw 方法
          Shape shape2 = shapeFactory.getShape("SQUARE");
          shape2.draw();
         
          //获取颜色工厂
          AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
          //获取颜色为 Red 的对象,调用 Red 的 fill 方法
          Color color1 = colorFactory.getColor("RED");
          color1.fill();
          //获取颜色为 Green 的对象,调用 Green 的 fill 方法
          Color color2 = colorFactory.getColor("Green");
          color2.fill();
       }
    }
    

    result

    The black cat is eating!
    The black dog is eating!
    The white cat is eating!
    The white dog is eating!
    
  • 相关阅读:
    ionic3打包打包安卓apk详细过程以及遇到的问题
    webpack+vue解决前端跨域问题
    在ionic3+angular4项目中添加自定义图标
    十. 图形界面(GUI)设计13.鼠标事件
    十. 图形界面(GUI)设计13.鼠标事件
    十. 图形界面(GUI)设计12.滚动条
    十. 图形界面(GUI)设计11.对话框
    十. 图形界面(GUI)设计10.菜单
    十. 图形界面(GUI)设计9.列表和组合框
    十. 图形界面(GUI)设计8.选择框和单选按钮
  • 原文地址:https://www.cnblogs.com/daozhangblog/p/12446374.html
Copyright © 2011-2022 走看看