• 设计模式之简单工厂模式


    简单工厂模式又叫做静态工厂方法模式,但不属于23种GOF设计模式,由于它太常用,因而将其放在首位,与后续的设计模式学习节奏保持一致。

    一、模式实现

    简单工厂将new对象的职责迁移到工厂中进行,通过传递的参数,在工厂中创建不同的实例化对象。下面通过具体的代码示例进行说明。

    问题:某公司有一种产品,现有AB两种生产方式,现要求对其创建逻辑进行实现,并将具体的创建产品逻辑进行隔离。

    现考虑用简单工厂模式的方法进行实现。

    两种创建方式的功能实现代码如下:

    public interface Product {
    	public void operator1();
    	public void operator2();
    }
    
    public class CreatProductA implements Product {
    
    	@Override
    	public void operator1() {
    		System.out.println("A产品进行1操作");
    	}
    
    	@Override
    	public void operator2() {
    		System.out.println("A产品进行2操作");
    	}
    }
    
    public class CreatProductB implements Product {
    
    	@Override
    	public void operator1() {
    		System.out.println("B产品进行1操作");
    	}
    
    	@Override
    	public void operator2() {
    		System.out.println("B产品进行2操作");
    	}
    }
    

    下面为简单工厂类的代码实现:

    public class SimpleFactory {
    	public static Product creatProduct(String type) {
    		Product product = null;
    		if ("A".equals(type)) {
    			product = new CreatProductA();
    		} else if ("B".equals(type)) {
    			product = new CreatProductB();
    		}
    		return product;
    	}
    }
    

    下面为客户端调用的代码:

    public class Client {
    	public static void main(String[] args) {
    		Product productA = SimpleFactory.creatProduct("A");
    		Product productB = SimpleFactory.creatProduct("B");
    	}
    }
    

    SimpleFactory通过Client中传递的参数type创建不同的Product实例对象。

    如下简单工厂的类图:

    注意:

    1、简单工厂可用来创建接口、抽象类及普通类的实例。

    2、在使用简单工厂的过程中通常没有创建工厂类实例的必要,因而常将简单工厂的方法写为静态的,故又静态工厂。

    3、一般应将简单工厂的创建范围控制在独立组件或模块级别,避免工厂职责混淆。

    简单工厂模式调用的时序图如下:

    二、模式说明

    简单工厂的本质是:选择实现,简单工厂用于为客户端选择相应的实现,可通过传递参数选择适当的实现类创建实例对象。选择方式主要有以下几种:

    • 来自客户端。由客户端选择的参数选择
    • 来自配置文件,从配置文件获取参数进行选择
    • 来源于程序,通过运行期间产生的值进行选择

    1、客户端传参

    通过客户端参数选择如下:

    public class Factory {
        public static Api creatApi(int type) {
            Api api = null;
            if (type == 1) {
                api = new ApiImpl1();
            } else if (type == 2) {
                api = new ApiImpl2();
            }
            return api;
        }
    }
    

    其中creatApi方法中根据传入的type值,创建不同的Api对象。

    缺点:客户端需理解传入的type值的含义,一定程度上暴露了代码的内部实现细节

    2、配置文件传参

    若添加新的创建API方法,则每次要修改工厂类,因而考虑其他实现工厂的方式,可通过配置文件的方式进行。

    一般开发中采用properties文件或xml文件方式进行配置:

    ApiImpl=com.luis.service.impl.ApiImpl3
    

    此时工厂的代码如下:

    public class Factory {
    	public static Api creatApi() {
    		Properties p = new Properties();
    		InputStream is = null;
    		try {
    			is = Factory.class.getResourceAsStream("ApiFactory.properties");
    			p.load(is);
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			try {
    				is.close();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    		Api api = null;
    		try {
    			api = (Api) Class.forName(p.getProperty("ApiImpl")).newInstance();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return api;
    	}
    }
    

    可通过配置文件实现简单工厂创建不同的实例化对象。

    三、模式总结

    1、使用场景

    • 需要完全封装隔离具体实现,外部只通过接口访问封装体,无需关心具体实现

    • 将创建对象的职责集中管理控制

    2、模式优缺点

    优点:

    • 帮助封装,真正实现面向接口编程。
    • 解耦,通过简单工厂实现客户端与具体实现类的解耦。
    • 简单工厂可通过一个含参的工厂方法,实例化任何产品类,戏称“上帝类”。

    缺点:

    • 增加客户端复杂度。通过客户端传参数在工厂中进行创建,增加客户端使用难度,暴露了内部实现。
    • 子工厂难扩展。私有化简单工厂的构造方法,使用静态方法创建接口,不方便子工厂的扩展。
    • 当所要生产产品种类非常多时,工厂方法的代码量可能会很庞大。
    • 遵循开闭原则(对拓展开放,对修改关闭)的条件下,简单工厂对于增加新的产品,只能通过修改工厂方法来实现。

    参考:文章主要参考《研磨设计模式》一书

  • 相关阅读:
    harmonOS分布式软总线
    harmonyOS的Ability是什么(一)FA的Page跳转和迁移
    转 微信支付商户如何处理微信申请退款、退款回调、查询退款接口
    转 Shiro笔记
    sql语句还能这么写(mysql脚步编写)
    Mac Shell 操作
    JSON.stringify 深拷贝的弊端以及常用场景
    elementplus elementui 官网文档如何查看
    QtQt使用QWebsocket实现服务端和客户端通信
    QtQt使用QRegExp实现正则表达式处理(Qt5.14.2+win10)
  • 原文地址:https://www.cnblogs.com/liuyi6/p/10339918.html
Copyright © 2020-2023  润新知