一、定义
简单工厂模式,又称为静态方法模式,属于类创建型的模式,可以根据参数的不同返回不同的类的实例。
二、类图
三、适用的环境
(1)工厂类创建的对象比较小,这样不会造成工厂方法中业务的逻辑过于复杂。
(2)客户端只是知道传入工厂类的参数、对于如何去创建对象并不关心。客户端不需要去关心创建的细节,只需要明确需要的参数,而由工厂内部负责具体的类的创建。
四、优点
(1)责任分割:工厂类含有处理逻辑,决定何时去创建产品对象,客户端只是需要传递对应的参数,即可以完成产品的创建。
(2)在一定程度上提高了系统的灵活性:可以通过引入配置文件的方法,在不去修改客户端代码的前提下,更换和增减新的产品。
五、缺点
(1)工厂类中集中了所有的判断处理逻辑,是整个系统的核心。
(2)系统拓展困难,如果去添加新的产品就不得不去修改工厂的逻辑,在产品类型较多时,需要修改工厂的内部逻辑,不利于系统的拓展和维护。
六、程序实例
(1)产品接口
1 package SimpleFactoryPattern; 2 3 /** 4 * @author jiaqing.xu@hand-china.com 5 * @version 1.0 6 * @name 7 * @description 抽象的TV类 8 * @date 2017/10/19 9 */ 10 public interface TV { 11 /** 12 * 电视机播放的方法 13 */ 14 public void play(); 15 }
(2)具体的电视类实现抽象接口
1 package SimpleFactoryPattern; 2 3 /** 4 * @author jiaqing.xu@hand-china.com 5 * @version 1.0 6 * @name 7 * @description 具体的电视类 海尔电视机 8 * @date 2017/10/19 9 */ 10 public class HaierTV implements TV { 11 @Override 12 public void play() { 13 System.out.println("海尔电视机播放中..."); 14 } 15 }
1 package SimpleFactoryPattern; 2 3 /** 4 * @author jiaqing.xu@hand-china.com 5 * @version 1.0 6 * @name 7 * @description 8 * @date 2017/10/19 9 */ 10 public class HisenseTV implements TV { 11 @Override 12 public void play() { 13 System.out.println("海信电视机播放中..."); 14 } 15 }
(3)产品工厂根据传入的参数的不同去实例化出不同的产品
1 package SimpleFactoryPattern; 2 3 /** 4 * @author jiaqing.xu@hand-china.com 5 * @version 1.0 6 * @name 7 * @description 电视机工厂 8 * @date 2017/10/19 9 */ 10 public class TVFactory { 11 /** 12 * 13 * @param brand 14 * @return 15 * @description 根据不同的brand去生成不同的TV 16 */ 17 public static TV produceTV(String brand) throws Exception { 18 //生产Haier电视机 19 if(brand.equalsIgnoreCase("Haier")){ 20 System.out.println("生产了一个Haier电视机."); 21 return new HaierTV(); 22 }else if(brand.equalsIgnoreCase("Hisense")){ 23 System.out.println("生产了一个Hisense电视机."); 24 return new HisenseTV(); 25 }else{ 26 throw new Exception("对不起,还不能生产该类型的电视机."); 27 } 28 } 29 }
(4)解析xml文件的工具类
1 package SimpleFactoryPattern; 2 3 import org.w3c.dom.Document; 4 import org.w3c.dom.Node; 5 import org.w3c.dom.NodeList; 6 import org.xml.sax.SAXException; 7 8 import javax.xml.parsers.DocumentBuilder; 9 import javax.xml.parsers.DocumentBuilderFactory; 10 import javax.xml.parsers.ParserConfigurationException; 11 import java.io.File; 12 import java.io.IOException; 13 14 /** 15 * @author jiaqing.xu@hand-china.com 16 * @version 1.0 17 * @name 18 * @description 19 * @date 2017/10/19 20 */ 21 public class XMLUtilTV { 22 /** 23 * 从xml中获取品牌的名称并返回该品牌名称 24 */ 25 public static String getBrandName() throws ParserConfigurationException, IOException, SAXException { 26 //创建文档对象读取工厂 27 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); 28 DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder(); 29 Document doc; 30 doc = builder.parse(new File("configTV.xml")); 31 32 //获取对应的文本节点 33 NodeList nodeList = doc.getElementsByTagName("brandName"); 34 Node classNode = nodeList.item(0).getFirstChild(); 35 String brandName = classNode.getNodeValue().trim(); 36 return brandName; 37 } 38 }
(5)config文件
1 <?xml version="1.0"?> 2 <config> 3 <brandName>Haier</brandName> 4 </config>
(6)测试方法
1 package SimpleFactoryPattern; 2 3 /** 4 * @author jiaqing.xu@hand-china.com 5 * @version 1.0 6 * @name 7 * @description 测试方法 8 * @date 2017/10/19 9 */ 10 public class Test { 11 public static void main(String[] args) throws Exception { 12 TV tv; 13 String brandName = XMLUtilTV.getBrandName(); 14 //传入品牌名称 生产电视机 15 tv = TVFactory.produceTV(brandName); 16 tv.play(); 17 } 18 }