1-1 工厂模式概述
模式的秘密---工厂模式——工厂模式概述 I
一、工程模式概念:
1、实例化对象,用工厂方法代替new操作;
2、包括工厂方法模式和抽象工厂模式;
3、抽象工厂模式是工厂模式的推广。
二、工厂模式的意图:
1、定义一个【接口】来创建对象,但是让子类来决定哪些类需要被实例化;
2、工厂方法把实例化的工作推迟到子类中去实现。
三、适合工厂模式的情况:
1、有一组类似的对象需要创建。
2、在编码的时候不能预见需要创建哪种类的实例。
3、系统需要考虑扩展性,不应依赖于产品类实例化如何被创建,组合和表达的细节。
四、项目中的现状: 在软件系统中经常面临着“对象”的创建工作,由于需求的变化,这个对象可能随之也会发生变化,但它却拥有比较稳定的接口。为此,我们需要提供一种封装机制来隔离出这个易变对象的变化,从而保持系统中其他依赖该对象的对象不随着需求变化而变化。 五、基于项目现状将代码进行如下设计:
1、尽量松耦合,一个对象的依赖对象的变化与本身无关;
2、具体产品与客户端剥离,责任分割。
2-1 工厂模式应用
模式的秘密---工厂模式——工厂模式应用 I 1、type.properties: left=com.sunny.project.LeftHair right=com.sunny.project.RightHair in=com.sunny.project.InHair 2、HairFactory .java /** * 发型工厂 * @author Administrator */ public class HairFactory { /** * 根据类型来创建对象 * @param key * @return */ public HairInterface getHair(String key){ if("left".equals(key)){ return new LeftHair(); }else if("right".equals(key)){ return new RightHair(); } return null; } /** * 原因:以上每次else if new 下太麻烦。 * 根据类的名称来生产对象 * @param className * @return */ public HairInterface getHairByClass(String className){ try { HairInterface hair = (HairInterface) Class.forName(className).newInstance(); return hair; } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null; } ...
模式的秘密---工厂模式——工厂模式应用 II /** * 原因:Class.forName(className) 每次要写那么长的路径类名太麻烦,利用配置文件来简化 * 根据类的名称来生产对象 * @param className * @return */ public HairInterface getHairByClassKey(String key){ try { Map
模式的秘密---工厂模式——工厂模式应用 III 3、HairInterface.java /** * 发型接口 * @author Administrator */ public interface HairInterface { /** * 画图 */ public void draw(); } 4、LeftHair.java(Right、In同理可得) /** * 左偏分发型 * @author Administrator */ public class LeftHair implements HairInterface { @Override public void draw() { System.out.println("左偏分发型"); } } 5、SunnyTest.java public class SunnyTest { public static void main(String[] args){ // HairInterface left = new LeftHair(); // left.draw(); HairFactory factory = new HairFactory(); // HairInterface right = factory.getHair("right"); // right.draw(); // HairInterface left = factory.getHairByClass("com.sunny.project.LeftHair"); // left.draw(); // HairInterface hair = factory.getHairByClassKey("in"); // hair.draw(); } } Ps【小技巧】:"left".equals(key),字符串放在左边可以避免当key为空时的异常。 3-1 抽象工厂模式应用
模式的秘密---工厂模式——抽象工厂模式应用 0、PersonFactory.java /** * 人物的实现接口 * @author Administrator */ public interface PersonFactory { //男孩接口 public Boy getBoy(); //女孩接口 public Girl getGirl(); } 1、Boy.java /** * 男孩子 * @author Administrator */ public interface Boy { public void drawMan(); } 2、Girl.java /** * 女孩子 * @author Administrator */ public interface Girl { public void drawWomen(); } 3、HNFactory.java /** * 新年系列加工厂 * @author Administrator */ public class HNFactory implements PersonFactory { @Override public Boy getBoy() { return new HNBoy(); } @Override public Girl getGirl() { return new HNGirl(); } } 4、HNBoy.java /** * 新年系列的男孩子 * @author Administrator */ public class HNBoy implements Boy { @Override public void drawMan() { System.out.println("新年系列的男孩子"); } } 5、HNGirl.java /** * 新年系列的女孩子 * @author Administrator */ public class HNGirl implements Girl { @Override public void drawWomen() { System.out.println("新年系列的女孩子"); } } Ps:圣诞
4-1 总结
模式的秘密---工厂模式——总结 I
1、接下来看spring beanfactory,这是非常有名的工具,我们知道spring容器是一个控制反转,主要作用是生成bean,管理bean,从工厂模式来看,spring beanfactory就是生产bean,然后提供给客户端。
2、来看一下bean实例化的过程:调用bena的默认构造方式生成bean的实例,暂称为instance1,如果在bean配置文件中注入了bean的属性,则在instance1基础上进行属性注入形成instance2,这种注入是覆盖性的,如果bean实现了InitializingBean接口,则调用afterPropertiesSet()方法,来改变或者操作instance2,得到instance3。其中:InitializingBean是spring提供的一个初始化bean的类,如果实现了这个类,则必须实现afterPropertiesSet()方法,接下来,如果bean的配置文件中指定了inti-method="init"属性,又会调用一个初始化方法,则在instance3的基础上又会进行一些改变,编程instance4.
模式的秘密---工厂模式——总结 II
一、工厂方法和抽象工厂方法的对比:
1)工厂模式是一种极端情况下的抽象工厂模式,而抽象工厂模式可以看成是工厂模式的推广;
2)工厂模式用来创建一个产品的等级结构,而抽象工厂模式是用来创建多个产品的等级结构;
3)工厂模式只有一个抽象产品类,而抽象工厂模式有多个抽象产品类,总之就是单一对多个产品的这种对比。
二、工厂模式帮助我们实现了什么呢:
1)系统可以在不修改具体工厂角色的情况下引进新的产品;
2)客户端不必关系对象如何去创建,明确了职责,对象具体的创建交给了具体的产品,product1,product2,客户端只要告诉工厂我需要哪一,product1还是product2,它们具体是怎么创建的,怎么组合的,都交给了具体的产品product1,product2; 3)更好的理解面向对象的原则,面向接口编程,而不是面向实现编程。那我们整体的工厂模式就是这样一个原则。
三、工厂模式适用于哪些场景呢:
1)一个系统应当不依赖于产品类实例被创立,组成和表示的细节,就是说这个产品如何被创建,组成和表现,我们都归结到具体的产品是如何实现上去了,与前端的client,和中端的factory都是没有关系的;
2)这个系统的产品至少有一个产品族,工厂方法模式就是一个产品族,它是最简单的一个等级;
3)同属于同一个产品族的产品是设计成在一起使用的,这是毋庸置疑的,同属于一个系列的产品,就是在一起的;
4)不同的产品以一系列的接口的面貌出现,从未使系统不依赖于接口实现的细节,我们都是面向接口编程的,不是面向实现编程的。
HairFactory.java
package com.sunny.project;
public class HairFactory {
public HairInterface getHair(String key){
if("left".equals(key)){
return new LeftHair();
}else if("right".equals(key)){
return new RightHair();
}
return null;
}
public HairInterface getHairByClass(String className){
try {
HairInterface hair = (HairInterface) Class.forName(className).newInstance();
return hair;
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
HairInterface.java
package com.sunny.project;
/*
* 发型接口
* */
public interface HairInterface {
public void draw();
}
SunnyTest.java
package com.sunny.project;
public class SunnyTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
// HairInterface left = new LeftHair();
// left.draw();
//为了实现与客户分离
HairFactory factory = new HairFactory();
// HairInterface left = factory.getHair("left");
// left.draw();
HairInterface left3 = factory.getHairByClass("com.sunny.project.LeftHair");
left3.draw();
}
}
LeftHair.java
package com.sunny.project;
//左偏分发型
public class LeftHair implements HairInterface {
@Override
public void draw() {
// TODO Auto-generated method stub
System.out.println("--------左偏分发型----");
}
}
RightHair.java
package com.sunny.project;
public class RightHair implements HairInterface {
@Override
public void draw() {
// TODO Auto-generated method stub
System.out.println("----------右偏分发型------");
}
}