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) ...
随机推荐
- Spring进阶-怎样集成定时调度Quartz
在一些项目里面比如进销存系统,对一些过期图片的定时清理或者库存不足发出预警提示,就需要用到定时调度技术. 每当经过一段时间,程序会自动执行,就是定时调度.如果要使用定时调度,则必须保证程序始终运行才行 ...
- 精通CSS高级Web标准解决方案(5、对列表应用样式和创建导航条)
5.1基本样式列表 去掉列表的默认样式: ul{ margin:; padding:; list-style-type:none; } 添加定制的符号,在列表左边添加填充,为符号留出空间,然后将符号图 ...
- Windows命令行中pip install jieba,但没有安装到anaconda3中
系统混淆了python3环境下的pip和anaconda3环境下的pip. 找到Anaconda3的Scripts目录,我这里是C:\Users\Diane\Anaconda3\Scripts 将该目 ...
- 单元测试-mock基础
本文较短,只是备份一下mock的几个常用基础例子方便复习 目录 介绍mock的使用例子 maven资源 <dependency> <groupId>org.mockito< ...
- PAT1039
小红想买些珠子做一串自己喜欢的珠串.卖珠子的摊主有很多串五颜六色的珠串,但是不肯把任何一串拆散了卖.于是小红要你帮忙判断一下,某串珠子里是否包含了全部自己想要的珠子?如果是,那么告诉她有多少多余的珠子 ...
- HDU3018 几笔画(非1笔)
Ant Trip Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- jQuery动态显示和隐藏datagrid中的某一列的方法
在EasyUI中: 1)展示某列的方法: $('#jgrid').datagrid('showColumn', 'XXX'); -----其中 XXX 是隐藏列的 field 属性值 2) ...
- Windows系统——后缀为.zip.00X的zip分卷解压
Windows下后缀为*.zip.001文件的解压方法: 后缀为*.zip.001文件用winrar无法解压, 解决办法是在windows下打开命令行界面, 输入:copy /B xx.zip.001 ...
- 【BZOJ 5047 空间传送装置】
Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 282 Solved: 121[Submit][Status][Discuss] Descriptio ...
- make gif pic
http://www.cockos.com/licecap/ licecap 1.open licecap 2.record ,make a pic filename,like pic1 3.work ...