对应慕课视频的连接: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. BZOJ 1531: [POI2005]Bank notes

    按余数分类 单调队列优化 #include<cstdio> using namespace std; int n,m,b[205],c[205],F[20005]; struct node ...

  2. 1180: [CROATIAN2009]OTOCI(LCT)

    1180: [CROATIAN2009]OTOCI Time Limit: 50 Sec  Memory Limit: 162 MBSubmit: 1200  Solved: 747[Submit][ ...

  3. axure rp教程(四)动态面板滑动效果

    转载自: http://www.iaxure.com/74.html 实现目标: 1.  点击登录滑出登录面板 2.  点击确定滑出动态面板 最终效果如下: 这种效果可以通过两种方法实现: 首先准备需 ...

  4. Analyze Program Runtime Stack

    Introduce: Process Explorer is an advanced process management utility that picks up where Task Manag ...

  5. 56、使用android studio(v1.3.*)修改包名 (rename package name)

    一.修改包名 ①选中目录,开始构造 在弹窗中选中Rename directory 在弹窗中选中Rename package 填写新的包名,点击Refactor 如果有警告,不用管它,直接点击Do Re ...

  6. linux环境搭建系列之maven

    前提: jdk1.7 Linux centOS 64位 安装包从官网获取地址:http://maven.apache.org/download.cgi Jdk1.7对应apache-maven-3.3 ...

  7. android adb常用指令

    介绍一个更详细的介绍ADB的: https://github.com/mzlogin/awesome-adb/blob/master/README.md ----------------------- ...

  8. json对象中根据主键判断是否有重复数据

    function funCheckRepeat() { var ids = $(gridId).jqGrid('getGridParam', 'selarrrow'); if (ids.length ...

  9. MFC之HTTP文件上传

    BOOL UploadFile(LPCTSTR strURL, LPCTSTR strLocalFileName) { // 如果URL为空或者文件不存在,直接返回 if (strURL == NUL ...

  10. Python机器学习数据挖掘工具sklearn安装和使用

    python借助pip安装第三方库,所以首先确保电脑上已成功安装了pip. 安装sklearn前需要先安装numpy.scipy和pandas等库.安装的方式有两种: 一.前往python的组件库页( ...