定义;定义一个工厂类,它可以根据参数的不同返回不同类的实例。
其包含3个角色;
工厂角色:负责实现创建所有产品实例的内部逻辑,提供了静态的工厂方法,返回类型为抽象产品类型
抽象产品角色:是工厂类所创建的所有对象的父类,封装了各种产品对象的共有方法
具体产品角色:是简单工厂模式的创建目标,每一个具体产品角色都继承了抽象产品角色。
简单的来说就是向一个方法传递不同的参数从而这个方法建立出不同的实例。
抽象产品角色:
比如一个农场类中有一个获得水果()方法
运行
农场.获得水果(苹果);//这时获得一个苹果的实例。
农场.获得水果(菠萝);//这时获得一个菠萝的实例。
这里农场是工厂类,获得水果()是工厂方法,水果是抽象产品角色,苹果、菠萝等是具体产品角色。优缺点及适用环境
优点:
(1)实现了对象的创建和使用的分离,客户端类不需要去创建对象,也不需要关注创建的细节,输入对应参数拿来即可用。
(2)工厂类实现了必要的逻辑判断,知道什么时机创建什么对象。
(3)引入配置文件,修改产品类可以通过修改配置文件实现,不需要修改任何代码。
缺点:
(1)工厂类工厂方法集中了所有类的创建逻辑判断,一旦该类无法正常工作,整个程序都将失效。
(2)系统扩展困难,想要添加产品就必须改动工厂方法的逻辑,在具体产品类较多时会使得工厂方法中的逻辑过于复杂。
(3)引入了工厂类,增加了类的个数,使得理解难度增加
(4)工厂方法使用了静态模式,造成工厂角色无法形成基于继承的等级结构。
适用环境;
(1)客户端不需要关系对象建立细节,只需要知道工厂类的参数
(2)具体角色类不能太多,工厂方法中的逻辑不能太过复杂。
简单实现代码
抽象产品类(水果)
Fruit
package simpleFactoryModel;
//抽象产品类(水果)
public interface Fruit {
//抽象方法用于输出(某些公共方法)
public void display();
}
工厂类(农场)
Fram
package simpleFactoryModel;
//工厂类(农场)
public class Fram {
public static Fruit getFuit(String type) {
Fruit fruit=null;
if (type.equalsIgnoreCase("Apple")) {
fruit=new Apple();
System.out.println("生成苹果成功");
}else if(type.equalsIgnoreCase("Pineapple")){
fruit=new Pineapple();
System.out.println("生成菠萝成功");
}
return fruit;
}
}
具体产品类(苹果)
Apple
package simpleFactoryModel;
//具体产品类-苹果
public class Apple implements Fruit{
public Apple() {
System.out.println("生成一个苹果");
}
public void display() {
System.out.println("显示苹果");
}
}
具体产品类(菠萝)
Pieapple
package simpleFactoryModel;
//具体产品角色菠萝
public class Pineapple implements Fruit{
public Pineapple() {
System.out.println("生成一个菠萝");
}
public void display() {
System.out.println("显示菠萝");
}
}
客户端
Client
package simpleFactoryModel;
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
Fruit fruit;
fruit=Fram.getFuit(Apple);
fruit.display();
}
}
运行结果为
我们也可以将工厂方法的参数放于一个配置文件中
建立名为congfig的配置文件和一个用来提取配置文件中的参数的工具类XMLUtil
config,xml
<config>
<fruitType>Apple</fruitType>
</config>
XMLUtil.java
package simpleFactoryModel;
//工具类读取配置文件的参数
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import java.io.*;
public class XMLUtil {
public static String getFriutType() {
try {
//创建文档对象
DocumentBuilderFactory dFactory= DocumentBuilderFactory.newInstance();
DocumentBuilder builder=dFactory.newDocumentBuilder();
Document doc=builder.parse(new File("src//simpleFactoryModel//config.xml"));
//获取包含图标的文本节点
NodeList nL=doc.getElementsByTagName("fruitType");
Node cNode=nL.item(0).getFirstChild();
String fruitType=cNode.getNodeValue().trim();
return fruitType;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
return null;
}
}
}
这时客户类修改为
Client.java
package simpleFactoryModel;
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
Fruit fruit;
String type =XMLUtil.getFriutType();
fruit=Fram.getFuit(type);
fruit.display();
}
}
运行结果同上
结构图