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) ...
随机推荐
- 常用Style
有些输入框什么的,字数限制什么的style,ceb为我们写好了.我感觉,每个app的style都是很有用的一个东西. <?xml version="1.0" encoding ...
- 1 - smart(Maven:Package,Install,&,Log4j2)
mvn package 时,增加如下命令-Dmaven.test.skip=true 则表示package打包时,不执行也不编译测试用例,mvn package -Dmaven.test.skip=t ...
- CA证书申请、认证原理
(一) 证书的申请 密钥文件的格式用OpenSSL生成的就只有PEM和DER两种格式,PEM的是将密钥用base64编码表示出来的,直接打开你能看到一串的英文字母,DER格式是二进制的密钥文件,直接打 ...
- IOS开发---菜鸟学习之路--(六)-UITableView几个方法的使用说明
对于UITableView的基础使用我这边就不做重复介绍了 我重点就来介绍下如何实现大部分新闻的界面.也就是第一条记录显示大图片下面加一段文字说明 然后剩下来的内容全部显示为文字图片的格式 其实要做到 ...
- 35、键盘布局的tableLayout备份
<TableLayout android:layout_width="wrap_content" android:layout_height="wrap_conte ...
- AppDOMain(摘录)
AppDomain是CLR的运行单元,它可以加载Assembly.创建对象以及执行程序. AppDomain是CLR实现 代码隔离 的基本机制. 每一个AppDomain可以单独运行.停止:每个App ...
- MoveWindow() SetWindowPos()的区别与联系
敲代码时,突然发现有一个背景图片无法显示,百思不得其解,最终发现是MoveWindow() SetWindowPos()这两个函数的使用不当造成的. 这里把这两个函数的前世今生给分析一下. 先看Mov ...
- Eclipse启动错误:A Java Runtime Environment(JRE) or Java Development Kit(JDK) must be available……
确保Jdk,Jre都安装完成并且环境变量配置无误的情况下,自动Ecplise报错如下: A Java Runtime Environment (JRE) or Java Development Kit ...
- 详细的Windows下安装 binwalk
1. https://github.com/ReFirmLabs/binwalk到这里下载binwalk,下载后解压. 2. 找到下载后的文件夹, 在这里要进行安装步骤,一边按着shift,一边按着鼠 ...
- Python面向对象之什么是类(1)
1.C#.Java :只能用面向对象编程 Ruby.Python :函数编程+ 面向对象 面向对象编程不是在所有地方都比函数式编程方便的,类是为了封装,下面是简单的使用方法 在创建类的时候要用clas ...