设计模式:工厂模式

本文探讨了如何在JavaScript中使用UML接口和工厂模式创建对象,以及在React中应用的例子。同时,对比了工厂模式与策略模式在业务场景中的差异。在React项目中,通过不同参数创建TablePie组件,利用工厂模式思想实现组件属性的动态配置。此外,还展示了JQuery的实现方式,进一步阐述了工厂模式的灵活性。
摘要由CSDN通过智能技术生成

UML 图

在这里插入图片描述

经典模式

interface IProduct {
    name: string
    fn1: () => void
    fn2: () => void
}

class Product1 implements IProduct {
    name: string
    constructor(name: string) {
        this.name = name
    }
    fn1() {
        console.log('Product1 fn1')
    }
    fn2() {
        console.log('Product1 fn2')
    }
}

class Product2 implements IProduct {
    name: string
    constructor(name: string) {
        this.name = name
    }
    fn1() {
        console.log('Product2 fn1')
    }
    fn2() {
        console.log('Product2 fn2')
    }
}

class Creator {
    // 依赖倒置原则(依赖于接口(抽象),而不是具体)
    // 这里的返回值并不取决于 Product1 或者 Product2
    // 哪怕有新的 Product 也不影响这里的返回值
    create(type: string, name: string): IProduct {
        if (type === 'p1') {
            return new Product1(name)
        } else if (type === 'p2') {
            return new Product2(name)
        } else {
            throw new Error('Invalid type')
        }
    }
}

const creator = new Creator()
const p1 = creator.create('p1', 'name1')
const p2 = creator.create('p2', 'name2')

JQuery 的实现

  • 文件路径:/node_modules/jquery/src/core/init.js
  • 思路: 通过不同的选择器类型,创建有不同属性的实例对象
  • 代码实现:
    init = jQuery.fn.init = function (selector, context, root) {
        var match, elem
    
        // HANDLE: $(""), $(null), $(undefined), $(false)
        if (!selector) {
            return this
        }
    
        // Method init() accepts an alternate rootjQuery
        // so migrate can support jQuery.sub (gh-2101)
        root = root || rootjQuery
    
        // Handle HTML strings
        if (typeof selector === 'string') {
            // ...
            // 其它字符串,当作选择器处理
    
            // HANDLE: $(DOMElement)
        } else if (selector.nodeType) {
            this[0] = selector
            this.length = 1
            return this
    
            // HANDLE: $(function)
            // Shortcut for document ready
        } else if (isFunction(selector)) {
            return root.ready !== undefined
                ? root.ready(selector)
                : // Execute immediately if ready is not present
                  selector(jQuery)
        }
    
        return jQuery.makeArray(selector, this)
    }
    

工厂模式与策略模式的区别

不知道大家在刚开始学习的时候,有没有这种感觉,如果是通过不同的参数创建有不同属性的对象,那和 策略模式 是不是有点像。
比如经典的计算年终奖代码:

  • 代码实现
    const performanceA = function(salary) {
        return salary * 4;
    };
    const performanceB = function(salary) {
        return salary * 3;
    };
            
    const performanceC = function(salary) {
        return salary * 2
    };
    
    const calculateBouns = function(level,salary) {
        if(level === 'A') {
            return performanceA(salary);
        }
        if(level === 'B') {
            return performanceB(salary);
        }
        if(level === 'C') {
            return performanceC(salary);
        }
    };
    
  • 区别
  1. 用途不一样

    工厂模式 是创建型模式,它的作用就是创建对象

    策略模式 是行为型模式,它的作用是让一个对象在许多行为中选择一种行为;

  2. 关注点不一样

    工厂模式 关注对象创建

    策略模式 关注行为的封装

  3. 解决不同的问题

    工厂模式 是创建型的设计模式,它接受指令,创建出符合要求的实例;它主要解决的是资源的统一分发,将对象的创建完全独立出来,让对象的创建和具体的使用客户无关。主要应用在多数据库选择,类库文件加载等。

    策略模式 是为了解决的是策略的切换与扩展,更简洁的说是定义策略族,分别封装起来,让他们之间可以相互替换,策略模式让策略的变化独立于使用策略的客户。

业务上的应用

经过一段时间的学习以后,公司主要用的技术栈是 react + typescript,我也遇到了觉得可以用上的场景,学以致用才能记住嘛,跟大家分享一下。通过不同的类型,创建具有不同属性的 TablePie 组件。从不太严格的角度上来看,应该也算是工厂模式吧

const indexMap = {
    所有营业部: 0,
    百万营业部: 1,
    新晋百万营业部: 2,
    '准片区/预备片区': 3,
}

function renderTablePie(radioVal) {
	const tableConfig = {
		// ... 初始属性
	}
	const pieChartConfig = {
		// ... 初始属性
	}
	
	switch (radioVal) {
	    case indexMap.所有营业部:
	    	// 不同类型配置不同的属性
	        return <TablePie tableConfig={tableConfig} pieChartConfig={pieChartConfig} />
	    case indexMap.百万营业部:
	    	// 不同类型配置不同的属性
	        return <TablePie tableConfig={tableConfig} pieChartConfig={pieChartConfig} />
	    case indexMap.新晋百万营业部:
	    	// 不同类型配置不同的属性
	        return <TablePie tableConfig={tableConfig} pieChartConfig={pieChartConfig} />
	    case indexMap['准片区/预备片区']:
	    	// 不同类型配置不同的属性
	        return <TablePie tableConfig={tableConfig} pieChartConfig={pieChartConfig} />
	    default:
	        return null
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值