如何使用工厂方法模式在Vue,React中创建不同类型的组件

326 阅读4分钟

工厂方法模式是一种创建型设计模式,它通过定义一个抽象的工厂接口和多个具体的工厂子类来创建不同类型的对象。工厂方法模式将对象的创建和客户端代码的耦合度降到最低,使得系统更加灵活和可扩展。

在前端开发中,工厂方法模式可以用于创建不同类型的组件,例如在Vue和React中创建不同类型的按钮组件。下面我们分别来介绍在Vue和React中如何使用工厂方法模式来创建不同类型的按钮组件。

在Vue中使用工厂方法

在Vue中使用工厂方法模式创建不同类型的按钮组件,我们可以首先定义一个抽象的工厂接口,如下所示:

// 定义抽象的工厂接口
class ButtonFactory {
  createButton() {}
}

然后,我们可以定义具体的工厂子类来实现这个接口,例如创建普通按钮和圆角按钮的工厂,代码如下:

// 创建普通按钮的工厂
class NormalButtonFactory extends ButtonFactory {
  createButton() {
    return {
      template: '<button>普通按钮</button>'
    }
  }
}

// 创建圆角按钮的工厂
class RoundButtonFactory extends ButtonFactory {
  createButton() {
    return {
      template: '<button class="round">圆角按钮</button>'
    }
  }
}

最后,在Vue的组件中使用这些工厂来创建对应类型的按钮组件,如下所示:

<template>
  <div>
    <component :is="button"></component>
  </div>
</template>

<script>
import NormalButtonFactory from './NormalButtonFactory'
import RoundButtonFactory from './RoundButtonFactory'

export default {
  name: 'ButtonContainer',
  data() {
    return {
      button: null
    }
  },
  created() {
    // 创建普通按钮
    const normalButtonFactory = new NormalButtonFactory()
    this.button = normalButtonFactory.createButton()

    // 创建圆角按钮
    const roundButtonFactory = new RoundButtonFactory()
    this.button = roundButtonFactory.createButton()
  }
}
</script>

在React中使用工厂方法模式

同样的,在React中使用工厂方法模式创建不同类型的按钮组件,我们也可以首先定义一个抽象的工厂接口,如下所示:

// 定义抽象的工厂接口
class ButtonFactory {
  createButton() {}
}

然后,我们可以定义具体的工厂子类来实现这个接口,例如创建普通按钮和圆角按钮的工厂,代码如下:

// 创建普通按钮的工厂
class NormalButtonFactory extends ButtonFactory {
  createButton() {
    return <button>普通按钮</button>
  }
}

// 创建圆角按钮的工厂
class RoundButtonFactory extends ButtonFactory {
  createButton() {
    return <button className="round">圆角按钮</button>
  }
}

最后,在React的组件中使用这些工厂来创建对应类型的按钮组件,如下所示:

import React from 'react'
import NormalButtonFactory from './NormalButtonFactory'
import RoundButtonFactory from './RoundButtonFactory'

class ButtonContainer extends React.Component {
  constructor(props) {
    super(props)
    this.state = { button: null }
  }

  componentDidMount() {
    // 创建普通按钮
    const normalButtonFactory = new NormalButtonFactory()
    const normalButton = normalButtonFactory.createButton()

    // 创建圆角按钮
    const roundButtonFactory = new RoundButtonFactory()
    const roundButton = roundButtonFactory.createButton()

    // 更新state
    this.setState({ button: normalButton })
    this.setState({ button: roundButton })
  }

  render() {
    const { button } = this.state
    return <div>{button}</div>
  }
}

export default ButtonContainer

可以看到,在React中使用工厂方法模式来创建不同类型的按钮组件和Vue非常类似,只不过React使用的是JSX语法,而Vue使用的是模板语法。

React Hooks中使用工厂方法

在React Hooks中使用工厂方法模式与在Class Components中使用类似,只是写法略有不同。下面我们来看一下如何在React Hooks中使用工厂方法模式。

首先,我们需要定义两个工厂类,分别用来创建不同类型的按钮组件:

// NormalButtonFactory.js
import NormalButton from './NormalButton'

export default function NormalButtonFactory() {
  function createButton() {
    return <NormalButton />
  }

  return {
    createButton
  }
}
// RoundButtonFactory.js
import RoundButton from './RoundButton'

export default function RoundButtonFactory() {
  function createButton() {
    return <RoundButton />
  }

  return {
    createButton
  }
}

然后,我们可以在自定义的Hooks中使用这两个工厂类来创建按钮组件:

// useButton.js
import React, { useState } from 'react'
import NormalButtonFactory from './NormalButtonFactory'
import RoundButtonFactory from './RoundButtonFactory'

export default function useButton() {
  const [button, setButton] = useState(null)

  React.useEffect(() => {
    const normalButtonFactory = new NormalButtonFactory()
    const normalButton = normalButtonFactory.createButton()
    setButton(normalButton)
  }, [])

  const handleClick = () => {
    const roundButtonFactory = new RoundButtonFactory()
    const roundButton = roundButtonFactory.createButton()
    setButton(roundButton)
  }

  return [button, handleClick]
}

在自定义Hooks中,我们使用React Hooks提供的useState钩子来创建一个button状态变量,并在组件挂载时使用NormalButtonFactory来创建初始的普通按钮组件。当按钮被点击时,我们使用RoundButtonFactory来创建一个新的圆角按钮组件,并将其设置为当前button状态的值。

最后,我们可以在组件中使用这个自定义的Hooks,如下所示:

import React from 'react'
import useButton from './useButton'

function ButtonContainer() {
  const [button, handleClick] = useButton()

  return (
    <div>
      <button onClick={handleClick}>Create Round Button</button>
      {button}
    </div>
  )
}

export default ButtonContainer

在组件中,我们调用useButton自定义Hooks,并使用返回的button状态变量和handleClick函数来更新组件状态。当用户点击"Create Round Button"按钮时,按钮组件将被更新为圆角按钮组件。

总的来说,无论是在Class Components还是在React Hooks中,使用工厂方法模式来创建不同类型的组件都是非常方便和灵活的。通过抽象的工厂接口和多个具体的工厂子类,我们可以轻松地创建不同类型的组件,将对象的创建和客户端代码的耦合度降到最低,从而实现更加灵活和可扩展的系统。

总结

总结一下,工厂方法模式是一种非常常用的设计模式,在前端开发中也有广泛的应用。无论是在Vue还是React中,使用工厂方法模式来创建不同类型的组件都是非常方便和灵活的。通过抽象的工厂接口和多个具体的工厂子类,我们可以轻松地创建不同类型的组件,将对象的创建和客户端代码的耦合度降到最低,从而实现更加灵活和可扩展的系统。