zoukankan      html  css  js  c++  java
  • 抽象工厂模式

    转自:《Java 设计模式》2009年( 耿祥义 张跃平 著)

    一,概括

    抽象工厂模式(别名:配套)

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

    二,引入

    设计某些系统是可能需要为用户提供一系列相关的对象,但系统不希望用户直接使用 new运算符 实例化这些对象,而是应由系统控制这些对象的创建。否则用户不仅要知道用哪些类来创建对象,而且还必须清楚这些对象之间是怎么相关的,使得用户的代码与这些类形成耦合,不利于维护。

    比如:商家要去工厂采购衣服裤子,这些商家自然不能自己生产衣服(直接使用 new运算符 实例化这些对象,用哪些类来创建对象).这些商家只能来到特定的工厂,他们自然会提供给你提供他们品牌的衣服。其中这些工厂是有生产配套的衣服和裤子的,商家也无需事先了解哪些衣服和裤子是一套的(对象之间是怎么相关的),工厂直接就提供给你一整套的衣物,这些衣物配套生产,这些商家也无法单独购买。商家只需要对工厂提供给你的样品衣物中做出选择,是否购买。

    三,代码与类图

    衣服有两种衣服,江牌风衣和鸟牌衬衫;裤子有两种裤子,江牌牛仔裤和鸟牌裙子;工厂有两座,一个是江牌的工厂。一个是鸟牌的工厂。

    package MM;
    
    /*************************
    	Clothes
    *************************/
    abstract class Clothes
    {
    	abstract public int getChestSize();
    	abstract public int getHeight();
    	abstract public String getName();
    }
    class WindCoat extends Clothes
    {
    	public int getChestSize()
    	{
    		return 90;
    	}
    	public int getHeight()
    	{
    		return 175;
    	}
    	public String getName()
    	{
    		return "江牌风衣";
    	}
    }
    class Shirt extends Clothes
    {
    	public int getChestSize()
    	{
    		return 90;
    	}
    	public int getHeight()
    	{
    		return 170;
    	}
    	public String getName()
    	{
    		return "鸟牌衬衫";
    	}
    }
    
    /*************************
    	Pants
    *************************/
    abstract class Pants
    {
    	abstract public int getWaistSize();
    	abstract public int getHeight();
    	abstract public String getName();
    }
    class Jeans extends Pants
    {
    	public int getWaistSize()
    	{
    		return 75;
    	}
    	public int getHeight()
    	{
    		return 175;
    	}
    	public String getName()
    	{
    		return "江牌牛仔裤";
    	}
    }
    class Skirt extends Pants
    {
    	public int getWaistSize()
    	{
    		return 62;
    	}
    	public int getHeight()
    	{
    		return 170;
    	}
    	public String getName()
    	{
    		return "鸟牌裙子";
    	}
    }
    
    /*************************
    	Factory
    *************************/
    abstract class Factory
    {
    	public Factory()
    	{
    		System.out.printf("生产了一套衣物:
    ");
    		System.out.printf(createClothes().getName() + ": 
    ");
    		System.out.printf("*胸围:" + createClothes().getChestSize() + "
    ");
    		System.out.printf("*身高:" + createPants().getHeight() + "
    ");
    		System.out.printf(createPants().getName() + ": 
    ");
    		System.out.printf("*腰围:" + createPants().getWaistSize() + "
    ");
    		System.out.printf("*身高:" + createPants().getHeight() + "
    ");
    		System.out.printf("
    ");
    	}
    	abstract public Clothes createClothes();
    	abstract public Pants createPants();
    }
    class JiangFactory extends Factory
    {
    	public Clothes createClothes()
    	{
    		return new WindCoat();
    	}
    	public Pants createPants()
    	{
    		return new Jeans();
    	}
    }
    class NiaoFactory extends Factory
    {
    	public Clothes createClothes()
    	{
    		return new Shirt();
    	}
    	public Pants createPants()
    	{
    		return new Skirt();
    	}
    }
    
    public class M
    {
    	public static void main(String L[])
    	{
    		Clothes c;
    		Pants p;
    		Factory f;
     
        		f = new JiangFactory();
            		c = f.createClothes();
    		p = f.createPants();
     
           		f = new NiaoFactory();
    		c = f.createClothes();
    		p = f.createPants();
    	}
    }
    

    类图:

     (注: 由于找不到合适的箭头,这箭头就画的不标准了)

    四,工厂方法模式的结构

    ① 抽象产品(Product): Clothes类 和 Pants类

    ② 具体产品(ConcreteProduct):  WindCoat类 和 Shirt类 和 Jeans类 和 Skirt类

    ③ 抽象工厂(Creator): Factory类

    ④ 具体工厂(ConcreteCreator): JiangFactory1类  和 NiaoFactory类

    五,抽象工厂模式的优缺点

    优点:

    ① 抽象工厂模式可以为用户创建一系列相关的对象,使用户和创建这些对象的类脱耦。

    ② 用户使用不同的具体工厂就能得到一组相关的对象,可以避免用户混用不同系列中的对象。

    ③ 在抽象工厂模式中,可以随时增加 “具体工厂”,为用户提供一组相关的对象。

    缺点:一旦原有的实体类进行扩充,就无法正常工作,(如在上述例子中,还要给 江牌 的套装增加一双袜子,就必须修改抽象工厂的代码了)

     六,抽象工厂模式的使用场景

    ① 系统需要为用户提供多个对象,又希望用户和创建对象的类脱耦。

    ② 系统需要为用户提供多个相关的对象,当又不希望用户决定这些对象是如何关联的。

    ③ 系统需要用户提供一系列对象,用户只需要知道有这些对象有哪些方法可用,不需要知道这些对象的创建过程。

    七,抽象工厂模式的使用

    用户在使用抽象工厂模式时,只和抽象产品,抽象工厂以及具体构工厂打交道,用户只需了解抽象产品有哪些方法,不需要知道有哪些具体产品。

    抽象工厂方法模式的关键是 在一个接口或抽象类中定义若干个 抽象方法(抽象工厂),这些方法分别返回某个类的子类的实例,该抽象类或接口 让其 子类或实现该接口的类(具体工厂) 通过重写这些抽象方法 为用户提供一系列相关的对象

    =========== ========= ======== ======= ===== ==== === == =

    蝶恋花  宋代: 柳永

    独倚危楼风细细,望极春愁,黯黯生天际。
    草色烟光残照里,无言谁会凭阑意。
    拟把疏狂图一醉,对酒当歌,强乐还无味。
    衣带渐宽终不悔,为伊消得人憔悴。
  • 相关阅读:
    命令基础
    绑定在表单验证上的应用
    绑定和绑定的各种使用场景
    双向数据绑定
    事件
    委托应用及泛型委托和多播委托
    委托
    LINQ
    反射重要属性方法
    反射基本内容
  • 原文地址:https://www.cnblogs.com/asdfknjhu/p/13962979.html
Copyright © 2011-2022 走看看