对应慕课视频的连接: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的更多相关文章

  1. 工厂方法(factory method)

    动机(Motivation) 在软件系统中,经常面临着“某个对象”的创建工作:由需求的变化,这个对象经常面临着剧烈的变化,但是它却拥有比较稳定的接口.如何应对这种变化?如何提供一种“封装机制”来隔离出 ...

  2. C#设计模式之二工厂方法模式(Factory Method Pattern)【创建型】

    一.引言 在上一篇文章中我们讲解了过渡的一种模式叫做[简单工厂],也有叫[静态工厂]的,通过对简单工厂模式得了解,我们也发现了它的缺点,就是随着需求的变化我们要不停地修改工厂里面的方法的代码,需求变化 ...

  3. 4.工厂方法模式(Factory Method)

    耦合关系:       动机(Motivation):    在软件系统中,由于需求的变化,"这个对象的具体实现"经常面临着剧烈的变化,但它却有比较稳定的接口.    如何应对这种 ...

  4. 面向对象设计模式纵横谈:Factory Method 工厂方法模式(笔记记录)

    从耦合关系谈起 耦合关系直接决定着软件面对变化时的行为 -模块与模块之间的紧耦合使得软件面对变化时,相关模块都要随之更改 -模块与模块之间的松耦合使得软件面对变化时,一些模块更容易被替换或者更改,但其 ...

  5. 抽象工厂(Abstract Factory),工厂方法(Factory Method),单例模式(Singleton Pattern)

    在谈工厂之前,先阐述一个观点:那就是在实际程序设计中,为了设计灵活的多态代码,代码中尽量不使用new去实例化一个对象,那么不使用new去实例化对象,剩下可用的方法就可以选择使用工厂方法,原型复制等去实 ...

  6. 创建型模式(二) 工厂方法模式(Factory Method)

    一.动机(Motivation) 在软件系统创建过程中,经常面临着"某个对象"的创建工作:由于需求的变化,这个对象(的具体实现)经常面临着剧烈的变化,但是它却拥有比较稳定的接口.如 ...

  7. C#面向对象设计模式纵横谈——5.Factory Method 工厂方法模式(创建型模式)

    动机 (Motivation) 在软件系统中,经常面临着“某个对象”的创建工作; 由于需求的变化,这个对象经常面临着剧烈的变化,但是它却拥有比较稳定的接口. 如何应对这种变化?如何提供一种“封装机制” ...

  8. C#设计模式系列:工厂方法模式(Factory Method)

    1. 工厂方法模式简介 1.1 定义 工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法模式是以一个类的实例化延迟到其子类. Factory Method模式用于在不指定待创建 ...

  9. 小菜学习设计模式(三)—工厂方法(Factory Method)模式

    前言 设计模式目录: 小菜学习设计模式(一)—模板方法(Template)模式 小菜学习设计模式(二)—单例(Singleton)模式 小菜学习设计模式(三)—工厂方法(Factory Method) ...

随机推荐

  1. 使用数组的splice方法以及循环嵌套来实现数组去重

    javascript代码如下   <script type="text/javascript"> var arr = [1,2,3,4,5,6,5,4,3,7,8,9, ...

  2. 查看2个Python字典的相同以及不同之处

    a = { "x":1, "y":2, "z":3 } b = { "x":1, "w":11, & ...

  3. Python3.0-3.6的版本变化

    Table of Contents Python3.0 简单的变化 语法的变化 新语法 改动的语法 剩下的变化 Python3.1 Python3.2 Python3.3 Python3.4 Pyth ...

  4. LuffyCity-MySQL综合练习50实例

    1.请创建如下表,并添加相应约束: 2.自行构造测试数据: 新建数据库 创建表 构造测试数据 #Step1-创建数据库LuffyCity_MySQL; #CREATE DATABASE LuffyCi ...

  5. jsp中/el表达式中将后台传来的时间戳格式化为年月日时分秒

    sp中/el表达式中将后台传来的时间戳格式化为年月日时分秒1.引入相关标签库 <%@taglib prefix="c" uri="http://java.sun.c ...

  6. Linux编程之变量

    Bash变量与变量分类 变量命名规则 变量名必须以字母或下划线打头,名字中间只能由字母.数字和下划线组成 变量名的长度不得超过255个字符 变量名在有效的范围内必须是唯一的 在Bash中,变量的默认类 ...

  7. [oldboy-django][4python面试]cookie和session比较

    session定义(知乎网上) Session的数据不是储存在客户端上的,而是储存在服务器上的:而客户端使用Cookie储存一个服务器分配的客户端会话序号(Session ID),当客户端请求服务器时 ...

  8. 如何删除本地docker images镜像

    背景 本地空间较小,想删除无效的docker镜像内容. 操作步骤 查看本地docker镜像 尝试删除本地镜像 发现无法直接删除镜像 原因分析: 有关联docker容器,无法删除 删除docker容器 ...

  9. docker常用命令整理

    Docker常见用法整理 Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器. Docker 容器通过 Docker 镜像来创建.容器与镜像的关系类似于 ...

  10. RNQOJ 开心的金明

    题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N 元钱就行”.今 ...