SimpleFactory
简单工厂: 通过对工厂传入参数即可返回所需的对象而不用知道具体的创建过程和发生的内部处理。
简单工厂不属于GoF模式之一
简单工厂包含以下几个角色:
- Factory : 工厂类,简单工厂模式的核心,负责创建所有实例类内部逻辑;工厂类可以被外部直接调用,创建所需要的产品对象;在工厂类中提供了静态的工厂方法,返回一个抽象产品类,所有的具体产品都是抽象产品的子类。
- Product: 抽象产品角色,简单工厂模式中所有创建的对象的父类,负责描述所有实例所共有的公共接口(抽象,并不实现内容,只提供公共接口)。根据多态原则,所有的具体产品都是他的子类,所以我们只需要在工厂类中定义一个工厂方法。
- ConreteProduct:具体产品,在一个工厂模式中,具体产品是有很多的。每一个具体产品都继承了抽象产品角色,并且需要实现公共接口。
接下来我们通过一段非常简单的代码来理解一下:
//抽象产品角色,并且定义抽象方法
public interface People {
void makepeople();
}
//具体产品,实现抽象方法
//这里为了说明只是简单实现抽象方法
class Man implements People{
public void makepeople(){
System.out.println("Man");
}
}
class Woman implements People{
public void makepeople(){
System.out.println("Woman");
}
}
class Robot implements People{
public void makepeople(){
System.out.println("Robot");
}
}
再来看工厂类:
//只要需要类名,不需要知道具体的创建过程
public class Nvwa {
public static People ProducePeople(final String sex) throws Exception{
if (sex.equalsIgnoreCase("M")){
System.out.println("女娲造出一个男孩");
return new Man();
}
else if (sex.equalsIgnoreCase("W")){
System.out.println("女娲造出一个女孩");
return new Woman();
}
else if (sex.equalsIgnoreCase("R")){
System.out.println("女娲造出一个Robot");
return new Robot();
}
else {
throw new Exception("Error!");
}
}
}
Client:
public class Client {
/**
* 这里利用系统工具类XMLUtilTV
* @param a
*/
public static void main(final String[] a){
try {
People p;
String sex = XMLUtilPeople.getsex();
p = Nvwa.ProducePeople(sex);
p.makepeople();
}
catch (Exception e){
System.out.println(e.getMessage());
}
}
}
外部工具只要创建一个抽象产品类,只要得到一个产品的名字,就可以通过工厂得到所需要的具体产品。
makepeople方法是抽象产品觉得的公共接口
工具类XMLUtil
public class XMLUtilPeople {
/**
* 该方法用于从XML配置文件中提取性别,并返回该性别;
*/
public static String getsex(){
try {
/**
* 创建文档对象
*/
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
// DocumentBuilder builder = dFactory.newDocumentBuilder();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("configpeople.xml"));
//获取包含性别的文本节点
NodeList nl = doc.getElementsByTagName("sex");
Node classNode = nl.item(0).getFirstChild();
String sex = classNode.getNodeValue().trim();
return sex;
} catch (Exception e){
e.printStackTrace();
return null;
}
}
}
xml配置文件:
<?xml version="1.0"?>
<config>
<sex>M</sex>
</config>
就是这么简单~
简单说一下简单工厂模式的优缺点
优点:
- 客户没有对创建产品对象具有责任,而仅仅只是使用通过工厂得到的具体产品
- 工厂内部对外封闭,使用者根本看不见工厂中的具体活动就能得到所要产品。将对象的创建和对象本身的业务处理分离,降低了系统的耦合度。模块和模块之间联系不大,修改起来比较轻松。
缺点:
- 工厂类中拥有大量的逻辑判断,一旦工厂类出现问题整个系统都要崩溃。
- 简单工厂模式的类数量是非常多的,在一定程度上增加了系统的复杂度和理解难度。
- 系统拓展困难,如果想要增加新的产品除了需要继承抽象产品角色实现公共接口,还需要在工厂类中修改对应的逻辑判断,这一点是违背了软件工程的代码开闭原则。