工厂模式包括:工厂方法模式和抽象工厂模式。
概念:
实例化对象,用工厂方法代替new操作。
工厂模式包括工厂方法模式和抽象工厂模式。
抽象工厂模式是工厂方法模式的扩展。
意图:
定义一个接口来创建对象,但是让子类来决定哪些类需要被实例化。
工厂方法把实例化的工作推迟到子类中去实现
应用场景:
1.有一组类似的对象需要创建
2.在编码时不能预见需要创建哪种类的实例
3.系统需要考虑扩展性,不应依赖于产品类实例如何被创建、组合和表达的细节
工厂方法模式和抽象工厂模式对比:
1.工厂模式是一种极端情况下的抽象工厂模式,而抽象工厂模式可以看成是工厂模式的推广
2.工厂模式用来创建一个产品的等级结构,而抽象工厂模式是用来创建多个产品的等级结构
3.工厂模式只有一个抽象产品类,而抽象工厂模式有多个抽象产品类
使用工厂模式的优点:
系统可以在不修改具体工厂角色的情况下引进新的产品
客户端不必关心对象如何创建,明确了职责
--------------------------------------------------示例代码(发型)------------------------------------------------------------------------------
发型接口 HairInterface 接口
public interface HairInterface {
public void draw();
}
发型左偏 LeftHair 类实现HairInterface 接口
public class LeftHair implements HairInterface {
@Override
public void draw() {
System.out.println("---------左偏----------------");
}
}
发型右偏 RighHair 类实现HairInterface 接口
public class RightHair implements HairInterface {
@Override
public void draw() {
System.out.println("----------------右偏-----------");
}
}
工厂 HairFactory类
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();
}else{
return null;
}
}}
客户端main方法
public static void main(String[] args) {
/*不用工厂模式 只能new*/
// HairInterface leftHair=new LeftHair();
// leftHair.draw();
HairFactory hairFactory=new HairFactory();
HairInterface left= hairFactory.getHair("left");
left.draw();
}
--------------------------------使用反射机制----根据类的名称来生产对象-------------------------------------------------------------
type.properties文件
left = LeftHair
right =RightHair
PropertiesReader类 读取properties文件
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**properties文件的读取工具
*
*/
public class PropertiesReader {
public Map<String,String> getProperties(){
Map<String,String> map =new HashMap<String,String>();
Properties properties=new Properties();
try {
InputStream ins=getClass().getResourceAsStream("type.properties");
properties.load(ins);
Enumeration enumeration=properties.propertyNames();
while (enumeration.hasMoreElements()){
String key=(String)enumeration.nextElement();
String property=properties.getProperty(key);
map.put(key,property);
}
} catch (IOException e) {
e.printStackTrace();
}
return map;
}
}
在 HairFactory类中新增 方法getHairByClass
/**
* 根据类的名称来生产对象
* @param
* @return
*/
public HairInterface getHairByClass(String key){
try {
PropertiesReader propertiesReader=new PropertiesReader();
Map<String,String> map= propertiesReader.getProperties(); //读取properties文件返回ma
HairInterface hairInterface=(HairInterface)Class.forName(map.get(key)).newInstance(); //根据类名称来生产对象
return hairInterface;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
客户端main方法
public static void main(String[] args) {
HairFactory hairFactory=new HairFactory();
HairInterface left= hairFactory.getHairByClass("right");
left.draw();
}
使用反射机制可以解决每次增加一个产品时,都需要增加一个对象实现工厂的缺点