Factory Method 和AbstractFactory
对应慕课视频的连接:https://www.imooc.com/video/5316
1,工厂模式的应用场景
有一组类似的对象需要被创建
在编码时不能预见需要被创建哪种类的实例
在系统需要考虑扩展性的情况下,不应依赖产品类实例如何创建,组合和表达的细节
2,项目中的现状:
在软件系统中经常面临着“对象”的创建工作,由于需求的变化,这个对象可能随之发生改变,但它却拥有比较稳定的接口。
为此我们需要提供一种风专辑之来隔离这个易变对象的变化,从而保持系统中其他依赖对该对象的对象不随着需求变化而改变

比如说,客户端要求生产苹果,creater就生产苹果,Uproduct就代表水果,他下面的Product1,Product2,Product3就可以表苹果,香蕉,橘子等具体的水果

在抽象工厂中呢,用户发出请求,factory生产水果,CreateFactory1,CreateFactory2他两个都可生产两种类型的水果,但是生产的具体产品又各不相同,CreateFactory1,CreateFactory2为两个系列。
一、代码部分(工厂模式实现)
(1)是定义生产头发的接口类
package com.songyan.factory;
/**
* 生产头发
* @author Administrator
*
*/
public interface Hair {
public void draw();
}
(2)定义生产发型的实现类:生产左偏分发型的类,生产右偏分发型的类
package com.songyan.factory;
public class LeftHair implements Hair{
@Override
public void draw() {
System.out.println("left hair");
}
}
package com.songyan.factory;
public class RightHair implements Hair{
@Override
public void draw() {
System.out.println("right hair");
}
}
(3)编写测试类,生产左偏分发型
package com.songyan.factory;
public class Test {
public static void test1()
{
Hair hair=new LeftHair();
hair.draw();
}
public static void main(String[] args) {
test1();
}
}
这种方法生产发型是在客户端生产,不安全------>在工厂中生产发型
(4)定义生产发型的工厂类
package com.songyan.factory; import java.util.HashMap;
import java.util.Map; public class HairFactory {
public static Hair getHair(String key)
{
Hair hair=null;
if("left".equals(key))
{
hair=new LeftHair();
}
else if("right".equals(key))
{
hair=new RightHair();
}
return hair;
} }
(5)编写对应的测试类
package com.songyan.factory;
public class Test {
public static void test1()
{
Hair hair=new LeftHair();
hair.draw();
}
public static void test2()
{
HairFactory factory=new HairFactory();
Hair hair=factory.getHair("left");
hair.draw();
}public static void main(String[] args) {
//test1();
test2();
}
}
这种方式,当添加新的发型时,需要在factory中添加新的else if判断(不合理)---->运用反射的技术,通过类名,动态的创建对象
反射的知识点:http://www.cnblogs.com/excellencesy/p/8868567.html
(6)通过反射创建对象
package com.songyan.factory; import java.util.HashMap;
import java.util.Map; public class HairFactory { public static Hair getHairByClass(String ClassName)
{
Hair hair=null;
try {
hair=(Hair) Class.forName(ClassName).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} return hair;
} }
通过传入累的全名,创建对应的对象
(7)对应的测试方法test3()
package com.songyan.factory;
public class Test {
public static void test1()
{
Hair hair=new LeftHair();
hair.draw();
}
public static void test2()
{
HairFactory factory=new HairFactory();
Hair hair=factory.getHair("left");
hair.draw();
}
public static void test3()
{
HairFactory factory=new HairFactory();
Hair hair=factory.getHairByClass("com.songyan.factory.LeftHair");
hair.draw();
}
public static void main(String[] args) {
//test1();
//test2();
test3();
}
}
这种方式需要输入复杂的类全名(不合理)----->配置简单的关键字
(8)编写配置文档type.properties
left=com.songyan.factory.LeftHair
right=com.songyan.factory.RightHair
(9)编写配置文档的读取类及方法
package com.songyan.factory; import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties; public class PropertiesReader {
public Map<String,String> getProperties()
{
//定义储存properties的map集合
Map<String ,String> map= new HashMap<String,String>();
//定义properties对象,操作Properties文件
Properties pro=new Properties();
//输入流以行的形式输入
InputStream in=getClass().getResourceAsStream("type.properties") ;
try {
pro.load(in); Enumeration enu=pro.propertyNames();
while(enu.hasMoreElements())
{
//
String key =(String)enu.nextElement();
String value=pro.getProperty(key);
map.put(key,value);
}
} catch (IOException e) {
e.printStackTrace();
} return map;
}
}
(10)编写相应的工厂方法
package com.songyan.factory; import java.util.HashMap;
import java.util.Map; public class HairFactory { public static Hair getHairByKey(String key)
{
Hair hair=null;
Map<String,String> map=new HashMap<String,String>();
PropertiesReader reader=new PropertiesReader();
map=reader.getProperties();
System.out.println(map);
String className=map.get(key);
try {
hair=(Hair) Class.forName(className).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return hair;
}
}
(11)编写对应的测试test4()
package com.songyan.factory;
public class Test {
public static void test4()
{
HairFactory factory= new HairFactory();
Hair hair=factory.getHairByKey("left");
hair.draw();
}
public static void main(String[] args) {
test4();
}
}
二、工厂模式的应用(抽象工厂)
抽象工厂的代码实现
(1)定义生产男孩子的接口、女孩子接口
package com.songyan.factory;
/**
* 男孩接口
* @author Administrator
*
*/
public interface Boy {
public void drawMan();
}
package com.songyan.factory;
/**
*女孩接口
* @author Administrator
*
*/
public interface Girl {
public void drawWomen();
}
(2)定义新年男孩,圣诞男孩 继承男孩,
定义新年女孩,圣诞女孩 继承女孩,
package com.songyan.factory;
/**
* 新年男孩
* @author Administrator
*
*/
public class HNBoy implements Boy{ @Override
public void drawMan() {
System.out.println("新年男孩"); } }
package com.songyan.factory;
/**
* 圣诞男孩
* @author Administrator
*
*/
public class MCBoy implements Boy{ @Override
public void drawMan() {
System.out.println("圣诞男孩");
} }
package com.songyan.factory;
/**
* 新年女孩
* @author Administrator
*
*/
public class HNGirl implements Girl{ @Override
public void drawWomen() {
System.out.println("新年女孩");
} }
package com.songyan.factory;
/**
* 圣诞女孩
* @author Administrator
*
*/
public class MCGirl implements Girl{ @Override
public void drawWomen() {
System.out.println("圣诞女孩"); } }
(3)定义生产男孩女孩的工厂接口
package com.songyan.factory;
/**
* 生产男孩女孩的工厂接口
* @author Administrator
*
*/
public interface PersonFactory {
//生产男孩子
public Boy getBoy();
//生产女孩子
public Girl getGirl();
}
(4)生产
新年
类型的男孩子,女孩子
package com.songyan.factory;
/**
* 生产新年类型的男孩子,女孩子
* @author Administrator
*
*/
public class HNFactory implements PersonFactory { @Override
public Boy getBoy() {
// TODO Auto-generated method stub
return null;
} @Override
public Girl getGirl() {
// TODO Auto-generated method stub
return null;
} }
(5)生产圣诞类型的男孩子,女孩子
package com.songyan.factory;
/**
* 生产圣诞类型的男孩子,女孩子
* @author Administrator
*
*/
public class MCFactory implements PersonFactory{ //
@Override
public Boy getBoy() {
return null;
} @Override
public Girl getGirl() {
return null;
} }
(6)编写测试类
package com.songyan.factory;
public class Test2 {
public static void main(String[] args) {
//绘制圣诞女孩
PersonFactory factory=new MCFactory();
Girl girl=factory.getGirl();
girl.drawWomen();
}
}
抽象工厂的应用
(1)数据库的链接

(2)生产bean返回给客户端


三、工厂模式总结


Factory Method 和AbstractFactory的更多相关文章
- 工厂方法(factory method)
动机(Motivation) 在软件系统中,经常面临着“某个对象”的创建工作:由需求的变化,这个对象经常面临着剧烈的变化,但是它却拥有比较稳定的接口.如何应对这种变化?如何提供一种“封装机制”来隔离出 ...
- C#设计模式之二工厂方法模式(Factory Method Pattern)【创建型】
一.引言 在上一篇文章中我们讲解了过渡的一种模式叫做[简单工厂],也有叫[静态工厂]的,通过对简单工厂模式得了解,我们也发现了它的缺点,就是随着需求的变化我们要不停地修改工厂里面的方法的代码,需求变化 ...
- 4.工厂方法模式(Factory Method)
耦合关系: 动机(Motivation): 在软件系统中,由于需求的变化,"这个对象的具体实现"经常面临着剧烈的变化,但它却有比较稳定的接口. 如何应对这种 ...
- 面向对象设计模式纵横谈:Factory Method 工厂方法模式(笔记记录)
从耦合关系谈起 耦合关系直接决定着软件面对变化时的行为 -模块与模块之间的紧耦合使得软件面对变化时,相关模块都要随之更改 -模块与模块之间的松耦合使得软件面对变化时,一些模块更容易被替换或者更改,但其 ...
- 抽象工厂(Abstract Factory),工厂方法(Factory Method),单例模式(Singleton Pattern)
在谈工厂之前,先阐述一个观点:那就是在实际程序设计中,为了设计灵活的多态代码,代码中尽量不使用new去实例化一个对象,那么不使用new去实例化对象,剩下可用的方法就可以选择使用工厂方法,原型复制等去实 ...
- 创建型模式(二) 工厂方法模式(Factory Method)
一.动机(Motivation) 在软件系统创建过程中,经常面临着"某个对象"的创建工作:由于需求的变化,这个对象(的具体实现)经常面临着剧烈的变化,但是它却拥有比较稳定的接口.如 ...
- C#面向对象设计模式纵横谈——5.Factory Method 工厂方法模式(创建型模式)
动机 (Motivation) 在软件系统中,经常面临着“某个对象”的创建工作; 由于需求的变化,这个对象经常面临着剧烈的变化,但是它却拥有比较稳定的接口. 如何应对这种变化?如何提供一种“封装机制” ...
- C#设计模式系列:工厂方法模式(Factory Method)
1. 工厂方法模式简介 1.1 定义 工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法模式是以一个类的实例化延迟到其子类. Factory Method模式用于在不指定待创建 ...
- 小菜学习设计模式(三)—工厂方法(Factory Method)模式
前言 设计模式目录: 小菜学习设计模式(一)—模板方法(Template)模式 小菜学习设计模式(二)—单例(Singleton)模式 小菜学习设计模式(三)—工厂方法(Factory Method) ...
随机推荐
- 使用数组的splice方法以及循环嵌套来实现数组去重
javascript代码如下 <script type="text/javascript"> var arr = [1,2,3,4,5,6,5,4,3,7,8,9, ...
- 查看2个Python字典的相同以及不同之处
a = { "x":1, "y":2, "z":3 } b = { "x":1, "w":11, & ...
- Python3.0-3.6的版本变化
Table of Contents Python3.0 简单的变化 语法的变化 新语法 改动的语法 剩下的变化 Python3.1 Python3.2 Python3.3 Python3.4 Pyth ...
- LuffyCity-MySQL综合练习50实例
1.请创建如下表,并添加相应约束: 2.自行构造测试数据: 新建数据库 创建表 构造测试数据 #Step1-创建数据库LuffyCity_MySQL; #CREATE DATABASE LuffyCi ...
- jsp中/el表达式中将后台传来的时间戳格式化为年月日时分秒
sp中/el表达式中将后台传来的时间戳格式化为年月日时分秒1.引入相关标签库 <%@taglib prefix="c" uri="http://java.sun.c ...
- Linux编程之变量
Bash变量与变量分类 变量命名规则 变量名必须以字母或下划线打头,名字中间只能由字母.数字和下划线组成 变量名的长度不得超过255个字符 变量名在有效的范围内必须是唯一的 在Bash中,变量的默认类 ...
- [oldboy-django][4python面试]cookie和session比较
session定义(知乎网上) Session的数据不是储存在客户端上的,而是储存在服务器上的:而客户端使用Cookie储存一个服务器分配的客户端会话序号(Session ID),当客户端请求服务器时 ...
- 如何删除本地docker images镜像
背景 本地空间较小,想删除无效的docker镜像内容. 操作步骤 查看本地docker镜像 尝试删除本地镜像 发现无法直接删除镜像 原因分析: 有关联docker容器,无法删除 删除docker容器 ...
- docker常用命令整理
Docker常见用法整理 Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器. Docker 容器通过 Docker 镜像来创建.容器与镜像的关系类似于 ...
- RNQOJ 开心的金明
题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N 元钱就行”.今 ...