1.1概述
提供一个创建一系列或相互依赖对象的接口,而无须指定他们具体的类。这就是抽象工厂模式的定义。
设计某些系统时可能需要为用户提供一系列相关的对象,但系统不希望用户直接使用new运算符实例化这些对象,而是应当由系统来控制这些对象的创建,否则用户不仅要清楚地知道使用哪些类来创建这些对象,而且还必须要清楚对象之间是如何关联的,使得用户的代码和这些类形成紧耦合、缺乏弹性、不利于维护。
图一:兵工厂与枪械、子弹关系示意图(PS:仅仅作为示意图,不要纠结哟)
当系统准备为用户提供一系列相关的对象,又不想让用户代码和创建这些对象的类形成耦合时,就可以使用抽象工厂方法模式来设计系统。抽象工厂模式的关键是在一个抽象类或接口中定义若干个抽象方法,这些抽象方法分别返回某个类的实例,该抽象类或接口让其子类或实现该接口的类重写这些抽象方法为用户提供一系列相关的对象。
1.2模式的结构
抽象工厂模式的结构中包括四种角色:
(1)抽象产品(Product):一个抽象类或接口,负责定义具体产品必须实现的方法;
(2)具体产品(ConcreteProduct):具体产品是一个类,如果Product是一个抽象类,那么具体产品就是实现Product的子类;如果Product是一个接口,那么具体产品就是实现Product接口的类;
(3)抽象工厂(AbstractFactory):一个接口或抽象类,负责定义若干个抽象方法;
(4)具体工厂(ConcreteFactory):如果抽象工厂是抽象类,具体工厂就是抽象工厂的子类;如果抽象工厂是一个接口,那么具体工厂就是实现抽象工厂接口的类。具体工厂重写抽象工厂中的抽象方法是该方法返回具体产品的实例。
抽象工厂模式的类图如下图二所示:
图二:抽象工厂模式结构类图
1.3抽象工厂模式的优点
(1)抽象工厂可以为用户创建一系列相关的对象,使用户和创建这些对象的类脱耦。
(2)使用抽象工厂模式可以方便为用户创建一系列对象。用户使用不同的具体工厂就能得到一组相关的对象,同时也能避免用户混用不用系列中对象。
(3)在抽象工厂模式中,可以随时增加“具体工厂”为用户提供一组相关的对象。
1.4适合使用抽象工厂模式的情景
(1)系统需要为用户提供多个对象,但不希望用户直接用new运算符实例化这些对象,即希望用户和创建对象脱耦。
(2)系统需要为用户提供一系列对象,但只需要知道这些对象有哪些方法可用,不需要用户知道这些对象的创建过程。
1.5抽象工厂模式的使用
以下通过一个简单的问题来描述抽象工厂模式中所涉及的各个角色。
建立一个系统,该系统可以为用户提供西服套装和牛仔套装,具体如下:
首先看一下本实例构建框架具体类和1.2模式的结构中类图的对应关系,如下图所示:
(1)抽象产品(Product)
抽象产品角色涉及两个类UpperClothes类和Trousers类,分别用来刻画衣服的上装和下装。UpperClothes类和Trousers类的代码如下:
UpperClothes.java
package com.liuzhen.eleven_abstractFactory; public interface UpperClothes { public abstract int getChestSize(); public abstract int getHeight(); public abstract String getName(); }
Trousers.java
package com.liuzhen.eleven_abstractFactory; public interface Trousers { public abstract int getWaistSize(); public abstract int getHeight(); public abstract String getName(); }
(2)具体产品(ConcreteProduct)
具体产品有四个类WesternUpperClothes、CowboyUpperClothes、WesternTrousers、CowboyTrousers,其中WesternUpperClothes和CowboyUpperClothes是UpperClothes类的子类,WesternTrousers和CowboyTrouser是Trousers类的子类。这四个具体类的代码如下:
WesternUpperClothes.java
package com.liuzhen.eleven_abstractFactory; public class WesternUpperClothes implements UpperClothes { private int chestSize; private int height; private String name; WesternUpperClothes(String name , int chestSize , int height){ this.name = name; this.chestSize = chestSize; this.height = height; } public int getChestSize() { // TODO Auto-generated method stub return chestSize; } public int getHeight() { // TODO Auto-generated method stub return height; } public String getName() { // TODO Auto-generated method stub return name; } }
CowboyUpperClothes.java
package com.liuzhen.eleven_abstractFactory; public class CowboyUpperClothes implements UpperClothes { private int chestSize; private int height; private String name; CowboyUpperClothes(String name , int chestSize , int height){ this.name = name; this.chestSize = chestSize; this.height = height; } public int getChestSize() { // TODO Auto-generated method stub return chestSize; } public int getHeight() { // TODO Auto-generated method stub return height; } public String getName() { // TODO Auto-generated method stub return name; } }
WesternTrousers.java
package com.liuzhen.eleven_abstractFactory; public class WesternTrousers implements Trousers { private int waistSize; private int height; private String name; WesternTrousers(String name , int waistSize , int height){ this.name = name; this.waistSize = waistSize; this.height = height; } public int getWaistSize() { // TODO Auto-generated method stub return waistSize; } public int getHeight() { // TODO Auto-generated method stub return height; } public String getName() { // TODO Auto-generated method stub return name; } }
CowboyTrousers.java
package com.liuzhen.eleven_abstractFactory; public class CowboyTrousers implements Trousers { private int waistSize; private int height; private String name; CowboyTrousers(String name , int waistSize , int height){ this.name = name; this.waistSize = waistSize; this.height = height; } public int getWaistSize() { // TODO Auto-generated method stub return waistSize; } public int getHeight() { // TODO Auto-generated method stub return height; } public String getName() { // TODO Auto-generated method stub return name; } }
(3)抽象工厂(AbstractFactory)
担当抽象工厂角色的类是ClothesFactory,代码如下:
package com.liuzhen.eleven_abstractFactory; public abstract class ClothesFactory { public abstract UpperClothes createUpperClothes(int chestSize , int height); public abstract Trousers createTrousers(int waistSize , int height); }
(4)具体工厂(ConcreteFactory)
有两个具体工厂,分别是BeijingClothesFactory类(负责制作西装套装)和ShanghaiClothesFactory类(负责制作牛仔套装),这两个类代码如下:
BeijingClothesFactory.java
package com.liuzhen.eleven_abstractFactory; public class BeijingClothesFactory extends ClothesFactory { @Override public UpperClothes createUpperClothes(int chestSize, int height) { // TODO Auto-generated method stub return new WesternUpperClothes("北京牌西服上衣",chestSize,height); } @Override public Trousers createTrousers(int waistSize, int height) { // TODO Auto-generated method stub return new WesternTrousers("北京牌西服裤子",waistSize,height); } }
ShanghaiClothesFactory.java
package com.liuzhen.eleven_abstractFactory; public class ShanghaiClothesFactory extends ClothesFactory { @Override public UpperClothes createUpperClothes(int chestSize, int height) { // TODO Auto-generated method stub return new CowboyUpperClothes("上海牌牛仔上衣",chestSize,height); } @Override public Trousers createTrousers(int waistSize, int height) { // TODO Auto-generated method stub return new CowboyTrousers("上海牌牛仔裤子",waistSize,height); } }
(5)模式的使用
首先看一下Shop类代码:
package com.liuzhen.eleven_abstractFactory; public class Shop { UpperClothes cloth; Trousers trouser; public void giveSuit(ClothesFactory factory , int chestSize , int waistSize , int height){ cloth = factory.createUpperClothes(chestSize, height); trouser = factory.createTrousers(waistSize, height); showMess(); } private void showMess(){ System.out.println("<套装信息>"); System.out.println(cloth.getName()+":"); System.out.println("胸围:"+cloth.getChestSize()); System.out.println("身高:"+cloth.getHeight()); System.out.println(trouser.getName()+":"); System.out.println("腰围:"+trouser.getWaistSize()); System.out.println("身高:"+trouser.getHeight()); } }
通过ElevenApplication类来具体实现上述相关类和接口,来实现抽象工厂模式的运用,其代码如下:
package com.liuzhen.eleven_abstractFactory; public class ElevenApplication { public static void main(String args[]){ Shop shop = new Shop(); ClothesFactory factory = new BeijingClothesFactory(); shop.giveSuit(factory, 110,82,170); factory = new ShanghaiClothesFactory(); shop.giveSuit(factory, 120, 88, 180); } }
运行结果:
<套装信息> 北京牌西服上衣: 胸围:110 身高:170 北京牌西服裤子: 腰围:82 身高:170 <套装信息> 上海牌牛仔上衣: 胸围:120 身高:180 上海牌牛仔裤子: 腰围:88 身高:180
相关推荐
以上就是压缩包中的设计模式学习笔记涉及到的主要内容。通过对这些模式的理解和应用,开发者可以更好地解决软件设计中的问题,提升软件的质量和可维护性。每种模式都有其适用场景,理解其背后的意图和应用场景是关键...
《设计模式学习笔记》主要探讨了GOF的23种设计模式以及类设计的基本原则,旨在帮助开发者理解和应用这些经过时间验证的成熟解决方案。设计模式是面向对象软件设计中的核心概念,它们为解决常见的设计问题提供了标准...
这里我们聚焦于C#语言中的设计模式学习笔记,涵盖了多种经典的设计模式,如合成模式、桥梁模式、装饰模式、享元模式、门面模式、命令模式、工厂方法、策略模式、代理模式以及状态模式。下面将对这些模式逐一进行详细...
《HeadFirst设计模式学习笔记》是一份详尽的资料,旨在帮助读者深入理解并掌握设计模式这一编程领域的核心概念。设计模式是软件工程中的一种最佳实践,它在解决常见问题时提供了一种标准的解决方案,使得代码更易于...
《C++20设计模式》学习笔记-第3章工厂方法和抽象工厂模式学习代码
这个“23种设计模式学习笔记”文档将引导你深入理解这些模式,并帮助你在实际编程中有效地应用它们。以下是对23种设计模式的详细解读: 1. **单例模式**:确保一个类只有一个实例,并提供全局访问点。它常用于控制...
以下是对“C#设计模式学习笔记”中涉及的一些关键知识点的详细解释。 1. **设计模式的基本概念**: 设计模式是一种在特定上下文中已被证明有效的解决方案模板,它描述了如何在软件设计中解决常见问题。设计模式...
这个压缩包文件包含了23种设计模式的学习笔记和源码,旨在帮助开发者深入理解并熟练运用这些模式。以下是对每种设计模式的详细解释,以及它们在Java编程中的应用。 1. **单例模式**:确保一个类只有一个实例,并...
在学习Java设计模式时,掌握其概念、应用、优点和缺点非常重要。设计模式是软件开发中经常使用的一种通用解决方案模板,用于解决特定上下文中的常见问题。它们源于设计模式的研究,通常被认为是软件设计中的最佳实践...
共150讲,时长共 33...1) 内容包括: 设计模式七大原则(单一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则、合成复用)、UML类图(类的依赖、泛化和实现、类的关联、聚合和组合) 23种设计模式包括...
设计模式的学习不仅帮助我们编写更可维护、可扩展的代码,还能提高团队间的沟通效率,因为它们提供了通用的语言和解决方案。在实际开发中,灵活运用这些设计模式可以有效解决设计问题,提升代码质量。因此,深入理解...
简单工厂模式是软件设计模式中的一种基础模式,它属于创建型模式,主要解决对象的创建问题,降低了系统与具体创建对象之间的耦合度。...对于更复杂的情况,可以考虑使用其他设计模式,如工厂方法模式、抽象工厂模式等。
"GoF 23种设计模式学习笔记" 是一个深入探讨这23个经典设计模式的资源,这些模式最初由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位作者在1994年的著作《设计模式:可复用面向对象软件的基础》中...
Java设计模式是软件开发中的重要概念,它是一种在特定情境下解决问题的经验总结,可以提高代码的可读性、可维护性和可复用性。这些模式是面向对象编程中的一种最佳实践,通过标准化的方式处理常见的设计问题。下面...
在这个“设计模式之美”的学习笔记中,我们将探讨一些主要的设计模式,以及它们在实际开发中的应用。 首先,我们从创建型模式开始。这类模式主要用于对象的创建,如单例模式(Singleton)、工厂模式(Factory ...
### Head.First 设计模式学习笔记知识点总结 #### 一、设计模式概述 设计模式是一种用于解决软件设计中常见问题的标准化方法。通过采用设计模式,开发者可以提高代码的复用性、灵活性和可维护性。《Head First 设计...