设计模式之简单工厂模式
来源:互联网 发布:简单网络协议实现 编辑:程序博客网 时间:2024/06/02 02:03
关于设计模式的学习笔记,教材:《设计模式的艺术之道》 刘伟 著
简单工厂模式是工厂模式的“小弟”,而工厂模式有一个“大哥”——抽象工厂模式。
Simple Factory Pattern: 定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常具有共同的父类。因为简单工厂模式中用于创建实例的方法是静态方法,因此该模式亦称为静态工厂方法模式,属于类创建型模式。
例:
使用简单工厂模式设计一个可以创建不同几何形状(如圆形、方形和三角形等)的绘图工具,每个几何图形都具有绘制和擦除两个方法,要求在绘制不支持的几何图形时,抛出一个UnSupportedShapeException。
interface Shape { void draw() throws UnSupportedShapeException; void erase();}public class Circle implements Shape { @Override public void draw() { System.out.println("圆形绘制"); } @Override public void erase() { System.out.println("圆形擦除"); } public Circle(){ System.out.println("圆形创建"); }}public class Rect implements Shape { @Override public void draw() { System.out.println("方形绘制"); } @Override public void erase() { System.out.println("方形擦除"); } public Rect(){ System.out.println("方形创建"); }}public class Triangle implements Shape { @Override public void draw() { System.out.println("三角形绘制"); } @Override public void erase() { System.out.println("三角形擦除"); } public Triangle(){ System.out.println("三角形创建"); }}public class UnSupportedShapeException extends Exception { public UnSupportedShapeException(String msg){ super(msg); }}public class ErrorShape implements Shape { private String type=null; @Override public void draw() throws UnSupportedShapeException { throw new UnSupportedShapeException("不支持 "+type+" 这种图形"); } @Override public void erase() { } public ErrorShape(String msg){ type=msg; }}public class SimpleFactory{ public static Shape getShape(String type) throws UnSupportedShapeException { Shape shape=null; String string=type.toLowerCase(); switch (string){ case "circle": shape=new Circle(); break; case "rectangle": shape=new Rect(); break; case "triangle": shape=new Triangle(); break; default: shape=new ErrorShape(string); break; } return shape; } public static void main(String[] args){ try { Shape a=getShape("triangle"); a.draw(); a.erase(); Shape b = getShape("cirCle"); b.draw(); b.erase(); Shape c=getShape("rectangle"); c.draw(); c.erase(); Shape d=getShape("olard"); d.draw(); /* 三角形创建 三角形绘制 三角形擦除 圆形创建 圆形绘制 圆形擦除 方形创建 方形绘制 方形擦除 designPattern.SimpleFactory.UnSupportedShapeException: 不支持 olard 这种图形 ... */ }catch (Exception e){ e.printStackTrace(); } }}
但是,在使用getShape("type")
创建具体的Shape对象时,每更换一个Shape对象都要修改参数,要重新编译,违反了开闭原则。
这时可以把参数存储在XML格式的配置文件中,如config.xml
<?xml version="1.0"?><config> <shapeType>triangle</shapeType> </config>
再通过一个工具类XMLUtil来读取配置文件中的字符串参数:
public class XMLUtil { public static String getShapeType() { try { //创建文档对象 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = builderFactory.newDocumentBuilder(); Document document = builder.parse(new File("config.xml")); NodeList nodeList = document.getElementsByTagName("shapeType"); Node node = nodeList.item(0).getFirstChild(); String shapeType = node.getNodeValue().trim(); return shapeType; } catch (Exception e) { e.printStackTrace(); return null; } }}
使用时略作修改
public static void main(String[] args){ try { Shape a; String type=XMLUtil.getShapeType(); a=getShape(type); a.draw(); a.erase(); }catch (Exception e){ e.printStackTrace(); } }
但是,当要添加新的具体图形类时,依然免不了要修改SimpleFactory的getShape方法。这如何解决呢?
这会在下一个设计模式——工厂方法模式中使用reflect(反射)解决。
优缺点
优点
- 实现了对象创建和使用的分离
- 减少使用者记忆量,比如rectangle类,有两个构造方法,分别是构造正方形和长方形的,我们不需要去记住其构造方法名和构造列表,只需要记住给getShape传什么参数即可
- 通过引入配置文件,可以在不修改客户端代码的情况下更换新的具体产品类,提高系统的灵活性。(如何要添加新的产品,要修改工厂类)
缺点
1. 工厂类包含了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都收到影响
2. 增加类的个数,增加系统复杂度和理解程度
3. 系统拓展困难,添加新产品必修修改工厂类的逻辑;具体产品类较多时,工厂逻辑过于复杂,不利于系统的拓展和维护
4. 简单工厂模式使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构?
适用场景
- 工厂类负责创建的对象较少
- 客户端只知道传入工厂类的参数,对于如何创建对象并不关心。
- 设计模式 之简单工厂+ 工厂模式
- 设计模式之简单工厂设计模式
- 设计模式之简单工厂模式,工厂模式,策略模式
- 设计模式 之 简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂.
- 设计模式之简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂
- 设计模式之简单工厂
- display: inline-block的妙用
- Android 5.0 Toolbar 的学习使用
- Android-RecyclerView(解析二)
- PAT 1067. Sort with Swap(0,*)
- Android小坑集锦
- 设计模式之简单工厂模式
- C/C++ sizeof函数解析——解决sizeof求结构体大小的问题
- Undefined symbols for architecture x86_64: "_OBJC_CLASS_$_WKWebView", referenced from: objc-
- 关于事务(Transaction)的几个概念
- ReactNative 中 ListView实现GridView效果
- 使用pyton写2048游戏
- linux,Vim和vi基本指令与使用
- 类的大小——sizeof 的研究
- mac 配置eclipse