Java的设计模式(4)--抽象工厂模式
提供一个创建一系列或相互依赖对象的接口,而无须指定他们具体的类。例如某些系统可能需要为用户提供一系列相关对象,但系统不希望用户直接使用new运算符实例化这些对象,而是应当由系统来控制这些对象的创建,否则用户不仅要清楚知道哪些类来创建对象,而且必须要清楚这些对象之间是如何相关的,使得用户代码和这些类型形成耦合,不利维护,一般会包括以下四种角色:
- 抽象产品(Product):一个抽象类或接口,负责定义具体产品必须实现的方法;
- 具体产品(ConcreteProduct):具体产品是一个类,如果Product是一个抽象类,那么具体产品是它的子类;如果Product是一个接口,那么具体产品是它的接口类;
- 抽象工厂(AbstractFactory):一个接口或抽象类,负责定义若干个抽象方法;
- 具体工厂(ConcreteFactory):如果抽象工厂是一个抽象类,具体工厂就是它的子类;如果是个接口就是它的实现类。具体工厂重写抽象工厂中的抽象方法,使该方法返回具体的产品实例。
抽象工厂的UML类图如下所示:
抽象工厂模式的优点:
- 可以为用户创建一系列相关的对象,使用户和创建这些对象的类脱藕。
- 可以方便的为用户配置一系列对象,用户使用不同的具体工厂就能得到一组相关的对象,同时也能避免用户混用不同系列中的对象。
- 可以随时增加具体工厂为用户提供一组相关的对象。
抽象工厂模式的应用场景:
- 系统需要为用户提供多个对象,但不希望用户直接使用new对象,希望用户和创建对象类的解耦
- 系统需要为用户提供多个相关的对象,以便用户联合使用他们,但又不希望用户来决定这些对象是如何关联的。
- 系统需要为用户提供一系列对象,但值需要用户知道这些对象有哪些方法可以用,不需要用户知道这些对象的创建过程
下面以服饰工厂生产衣服为例,为用户提供西装和牛仔裤:
1. 抽象产品,裤子和上衣
public abstract class Trousers { public abstract int getWaitstSize();
public abstract int getHeight();
public abstract String getName();
}
public abstract class UpperClothes { public abstract int getChestSize();
public abstract int getHeight();
public abstract String getName();
}
2. 具体产品
public class CowBoyTrouers extends Trousers {
private int waistSize;
private int height;
private String name; public CowBoyTrouers(int waistSize, int height, String name) {
this.waistSize = waistSize;
this.height = height;
this.name = name;
} @Override
public int getWaitstSize() {
return waistSize;
} @Override
public int getHeight() {
return height;
} @Override
public String getName() {
return name;
} }
public class WesternTrouers extends Trousers { private int waistSize;
private int height;
private String name; public WesternTrouers(int waistSize, int height, String name) {
this.waistSize = waistSize;
this.height = height;
this.name = name;
} @Override
public int getWaitstSize() {
return waistSize;
} @Override
public int getHeight() {
return height;
} @Override
public String getName() {
return name;
}
}
public class CowBoyUpperClothes extends UpperClothes { private int chextSize;
private int height;
private String name; public CowBoyUpperClothes(int chextSize, int height, String name) {
super();
this.chextSize = chextSize;
this.height = height;
this.name = name;
} @Override
public int getHeight() {
return height;
} @Override
public String getName() {
return name;
} @Override
public int getChestSize() {
return chextSize;
}
}
public class WesternUpperClothes extends UpperClothes { private int chestSize;
private int height;
private String name; public WesternUpperClothes(int chestSize, int height, String name) {
super();
this.chestSize = chestSize;
this.height = height;
this.name = name;
} @Override
public int getChestSize() {
return chestSize;
} @Override
public int getHeight() {
return height;
} @Override
public String getName() {
return name;
} }
3. 抽象工厂
public abstract class ClotherFactory { public abstract UpperClothes createUpperClothes(int chestSize,int height);
public abstract Trousers createTrousers(int waistSize,int height);
}
4.具体工厂,一个负责生产西装,一个负责制作牛仔
public class BJClotherFactory extends ClotherFactory { @Override
public UpperClothes createUpperClothes(int chestSize, int height) {
return new WesternUpperClothes(chestSize,height,"北京牌西服上衣");
} @Override
public Trousers createTrousers(int waistSize, int height) {
return new WesternTrouers(waistSize, height,"北京牌西服裤子");
} }
public class SHClothesFactory extends ClotherFactory { @Override
public UpperClothes createUpperClothes(int chestSize, int height) {
return new CowBoyUpperClothes(chestSize, height, "上海牌牛仔上衣");
} @Override
public Trousers createTrousers(int waistSize, int height) {
return new CowBoyTrouers(waistSize, height, "上海牌牛仔裤子");
} }
上面这些类就是一个小框架,可以使用这个小框架编写自己的类。应用程序在使用抽象工厂模式时,只和抽象的产品、抽象工厂以及具体工厂打交道,用户只需要了解抽象产品有哪些方法即可,不需要知道有哪些具体产品。下列代码列出了一个应用程序的类。
public class Shop { private UpperClothes cloth;
private Trousers trouser;
public void giveSuit(ClotherFactory factory,int chestSize,int waistSize,int height){
this.cloth = factory.createUpperClothes(chestSize, height);
this.trouser = factory.createTrousers(waistSize, height);
showMess();
}
private void showMess() {
System.out.println("<套装信息>");
System.out.println(cloth.getName()+":");
System.out.print("胸围:"+cloth.getChestSize());
System.out.println(" 身高:"+cloth.getHeight());
System.out.println(trouser.getName()+":");
System.out.print("腰围:"+trouser.getWaitstSize());
System.out.println(" 身高"+trouser.getHeight());
}
}
public class Application { public static void main(String[] args) {
Shop shop = new Shop();
ClotherFactory facory = new BJClotherFactory();
shop.giveSuit(facory, 110, 82, 170);
facory = new SHClothesFactory();
shop.giveSuit(facory, 120, 88, 180);
}
}
Java的设计模式(4)--抽象工厂模式的更多相关文章
- Java 设计模式之抽象工厂模式(三)
原文地址:Java 设计模式之抽象工厂模式(三) 博客地址:http://www.extlight.com 一.前言 上篇文章 <Java 设计模式之工厂模式(二)>,介绍了简单工厂模式和 ...
- 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)
原文:乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factor ...
- 桥接模式及C++实现 C++设计模式-AbstractFactory抽象工厂模式
桥接模式及C++实现 桥接模式 先说说桥接模式的定义:将抽象化(Abstraction)与实现化(Implementation)分离,使得二者可以独立地变化. 桥接模式号称设计模式中最难理解的模式之一 ...
- java设计模式之抽象工厂模式
上一篇文章(http://www.cnblogs.com/liaoweipeng/p/5768197.html)讲了简单工厂模式,但是简单工厂模式存在一定的问题,如果想要拓展程序,必须对工厂类进行修改 ...
- Java设计模式系列-抽象工厂模式
原创文章,转载请标注出处:https://www.cnblogs.com/V1haoge/p/10755412.html 一.概述 抽象工厂模式是对工厂方法模式的再升级,但是二者面对的场景稍显差别. ...
- java设计模式(三)--抽象工厂模式
转载:http://zz563143188.iteye.com/blog/1847029 前面的工厂方法模式虽然清晰,但还是感觉有些繁琐,通常使用的还是抽象工厂模式. 工厂方法模式有一个问题就是,类的 ...
- Java 设计模式之抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂.该超级工厂又称为其他工厂的工厂.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 在抽 ...
- [java] java 设计模式(2):抽象工厂模式(Abstract Factory)
工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这 ...
- 设计模式之抽象工厂模式(Java实现)
“上次是我的不对,贿赂作者让我先讲来着,不过老婆大人大人有大量,不与我计较,这次还让我先把上次未讲完的应用场景部分给补充上去,有妻如此,夫复何求.”(说完,摸了摸跪的发疼的膝盖,咳咳,我发四我没笑!真 ...
- Java设计模式(3)——抽象工厂模式
抽象工厂模式是所有形态的工厂模式中最为抽象和最其一般性的.抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,能够创建多个产品族的产品对象. 一.产品族和产品等级结构 为 ...
随机推荐
- java 通过runtime 调用python 不显示python运行内容的bug
先说下上面问题的原因,上面问题是因为python中用到了第三方的类库,你的电脑上没有那个类库,所以程序没有运行,在控制台也就看不到输出.只要导入那个类库就好... python 导入类库,可以单独下载 ...
- C++的面向对象的Dijkstra写法
C++的面向对象的Dijkstra写法 面向对象特点的充分使用 清晰的逻辑 简洁的图输入 程序 面向对象特点的充分使用 清晰明确的类实现 class Edge(边的实现) class Req (路由请 ...
- Java 面向对象(十一)
常用类之集合 集合:就是用来存放数据的一个容器. 数组和集合的区别 (1)数组能存基本数据类型和引用类型:集合当中只能存放引用数据类型,直接放基本数据类型,也会自动帮你装箱(把基本数据类型转成对象), ...
- Elasticsearch6.4.0-windows环境部署安装
Elasticsearch可以轻松的实现全文检索,本文主要介绍Elasticsearch(ES)环境的安装部署,该文及后续使用的ES版本为6.4.0.希望能够帮助到大家. 一.安装Elasticsea ...
- Linux后台运行任务
[Linux]ssh命令行下多任务前后台切换 原文:https://my.oschina.net/huxuanhui/blog/13844 我们都知道,在 Windows 上面,我们要么让一个程序作为 ...
- arcgis python 使用光标和内存中的要素类将数据加载到要素集 学习:http://zhihu.esrichina.com.cn/article/634
学习:http://zhihu.esrichina.com.cn/article/634使用光标和内存中的要素类将数据加载到要素集 import arcpy arcpy.env.overwriteOu ...
- 分享CSS3里box-shadow属性的使用方法,包括内阴影box-shadow:inset
一.box-shadow语法 box-shadow: none | inset(可选值,不设置,为外投影,设置,为内投影) x-offset(阴影水平偏移量,正方向为right) y-offset(阴 ...
- Webpack中的sourcemap以及如何在生产和开发环境中合理的设置
一 . 从Sourcemap和Data URL说起 (1)什么是Sourcemap? 我们在打包中,将开发环境中源代码经过压缩,去空格,babel编译转化,最终可以得到适用于生产环境的项目代码,这样处 ...
- GDPR全文翻译(一)
General Data Protection Regulation <一般数据保护法案>全文翻译(一) 编者按 2016年4月14日,欧洲议会投票通过了商讨四年的<一般数据保护法案 ...
- django 2 ORM操作 ORM进阶 cookie和session 中间件
ORM操作 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描述 ...