惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

量子位
S
Securelist
MyScale Blog
MyScale Blog
Jina AI
Jina AI
罗磊的独立博客
The Cloudflare Blog
美团技术团队
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
博客园 - 三生石上(FineUI控件)
月光博客
月光博客
雷峰网
雷峰网
小众软件
小众软件
aimingoo的专栏
aimingoo的专栏
大猫的无限游戏
大猫的无限游戏
博客园 - Franky
博客园 - 聂微东
Y
Y Combinator Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
MongoDB | Blog
MongoDB | Blog
T
Tailwind CSS Blog
Attack and Defense Labs
Attack and Defense Labs
博客园_首页
Latest news
Latest news
Apple Machine Learning Research
Apple Machine Learning Research
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
The Hacker News
The Hacker News
G
GRAHAM CLULEY
Simon Willison's Weblog
Simon Willison's Weblog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Proofpoint News Feed
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
U
Unit 42
D
Docker
Webroot Blog
Webroot Blog
N
Netflix TechBlog - Medium
T
Tor Project blog
C
Cyber Attacks, Cyber Crime and Cyber Security
L
LINUX DO - 最新话题
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
The Last Watchdog
The Last Watchdog
B
Blog
Recent Announcements
Recent Announcements
GbyAI
GbyAI
Microsoft Azure Blog
Microsoft Azure Blog
Security Latest
Security Latest
V2EX - 技术
V2EX - 技术
N
News | PayPal Newsroom
Microsoft Security Blog
Microsoft Security Blog

博客园 - bala001

【记录】一文搞懂pinia状态管理(保姆级教程) 前端开发设计模式:原型模式 2025 年前端面试中常见问题 Object.create 前端开发设计模式:工厂模式(Factory Pattern)【上】 前端开发设计模式:单例模式之场景应用&实现 前端开发设计模式:架构 前端开发设计模式: 单例模式(Singleton Pattern) JS篇之JS类型 2024/10/20: TypeScript 学习笔记三:TypeScript 类型系统 博文阅读密码验证 - 博客园 2024/09/22:TypeScript 学习笔记二 2024/09/20: TypeScript 学习笔记一 css 技巧 博文阅读密码验证 - 博客园 博文阅读密码验证 - 博客园 45 个每个开发人员都应该知道的 JavaScript 超级技巧 - 抄录 明确学习路径与方法 开篇词 - 《重学前端》
前端开发设计模式:工厂模式(Factory Pattern)【下】
bala001 · 2025-03-18 · via 博客园 - bala001

承接上文:《前端开发设计模式:工厂模式(Factory Pattern)【上 】

三、常用场景

简单工厂模式

 场景特点:适用于创建对象逻辑简单,且产品类型相对较且需求相对稳定,不经常添加新的产品类型的场景。

具体应用

例1:创建不同类型的 表单/按钮 组件,组件类型固定且后续不太可能有大量新类型添加

<!-- text-input.vue  子组件 应该存在多个 -->
<template>
  <input type="text" />
</template>
<script setup lang="ts" name="TextInput"></script>
// factories.js --- 创建工厂函数
import TextInput from '@/components/text-input.vue'
import SelectInput from '@/components/select-input.vue'

const componentFactory = {
    createComponent(type){
        const components = {
            'A': TextInput,
            'B': SelectInput
            // 可扩展其他组件
        }
        if(!components[type]){
            console.error(`未找到类型为${type}的组件`)
            return null // 或返回默认组件
        }
        return components[type]
    }
}
export default componentFactory
<!-- parent.vue --- 在组件中使用工厂模式 -->
<template>
  <div>
    <!-- 动态组件渲染 -->
    <component :is="currentComponent" v-if="currentComponent"></component>
  </div>
</template>
<script setup lang="ts">
import componentFactory from "./factories.js";

const props = defineProps({
  type: {
    type: String,
    default: "",
  },
});

// 工厂函数动态获取组件
const currentComponent = computed(() => {
  return componentFactory.createComponent(props.type);
});
</script>

从这个示例中可以明确看出工厂模式的优点就是将创建与使用分离。

例2:根据用户的权限级别创建不同的导航菜单组件

// menu-factory.js

// 定义基础导航菜单类
class BaseNavMenu {
  constructor() {
    this.lists = [];
  }
  render() {
    return this.lists;
  }
}

// 定义普通用户导航菜单类
class NormalUserNavMenu extends BaseNavMenu {
  constructor() {
    super();
    this.lists = [
      {
        name: "首页",
        path: "/",
      },
      {
        name: "关于我们",
        path: "/about",
      },
      {
        name: "联系我们",
        path: "/contact",
      },
    ];
  }
}

// 定义管理员用户导航菜单类
class AdminUserNavMenu extends BaseNavMenu {
  constructor() {
    super();
    this.lists = [
      {
        name: "首页",
        path: "/",
      },
      {
        name: "用户管理",
        path: "/users",
      },
      {
        name: "文章管理",
        path: "/articles",
      },
      {
        name: "关于我们",
      },
    ];
  }
}

// 定义导航菜单工厂函数
function NavMenuFactory(role){
    switch (role) {
        case 1:
            return new NormalUserNavMenu();
        case 0:
            return new AdminUserNavMenu();
        default:
            throw new Error('Invalid role');
    }
}
<!-- menu.vue -->
<template>
  <div class="menu-container">
    <div
      v-for="item in menuList"
      :key="item.name"
      @click.stop="toPage(item.path)"
    >
      {{ item.name }}
    </div>
  </div>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import menuFactory from "./menu-factory.js";

const props = defineProps({
  userLevel: {
    type: Number,
    required: true,
  },
});

const menuList = ref([]);

menuList.value = menuFactory(props.userLevel).render();
</script>

例3:游戏中创建不同的游戏角色。--- 代码差不多就不实现了。

工厂方法模式

将对象的创建抽成一个抽象方法,由具体子类实现这个方法,符合开闭原则。

场景特点:适用于创建对象的逻辑较为复杂,且产品类型较多,需频繁扩展的场景

具体应用

 例1:电商系统中,商品类型不断增加,比如有普通商品,促销商品,限时抢购商品等,每种商品的创建逻辑不同。

// factories.js

import EmptyComponent from "./empty-component.vue";
import NormalComponent from "./normal-component.vue";
import PromotionComponent from "./promotion-component.vue";

class Product {
  showComponents() {
    console.log("该方法必须被重写");
    return EmptyComponent;
  }
}
// 产品子类
class NormalProduct extends Product {
  showComponents() {
    return NormalComponent;
  }
}
class promotionProduct extends Product {
  showComponents() {
    return PromotionComponent;
  }
}

class ProductFactory {
  createProduct() {
    throw new Error("抽象类不能实例化,该方法必须重写");
  }
}
class NormalProductFactory extends ProductFactory {
  createProduct() {
    return new NormalProduct();
  }
}
class PromotionProductFactory extends ProductFactory {
  createProduct() {
    return new promotionProduct();
  }
}

export { NormalProductFactory, PromotionProductFactory };
<!-- detail.vue -->
<template>
  <div class="detail-container">
    <component :is="currentComponents"></component>
  </div>
</template>
<script lang="ts" setup>
import { NormalProductFactory, PromotionProductFactory } from "./factories.js";
const props = defineProps({
  detail: {
    type: Object,
    default: () => {},
    required: true,
  },
});
const currentComponents = computed(() => {
  let _facotry;
 // 这里可以用简单工厂模式的思想,写个方法
if (props.detail.productType === "promotion") { _facotry = new PromotionProductFactory(); } else { _facotry = new NormalProductFactory(); } const _computer = _facotry.createComputer(); return _computer.showComponents(); }); </script>

例2:日志系统中,创建不同类型的日志记录器。--- 代码差不多就不实现了。

抽象工厂模式

抽象工厂模式提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。它可以创建多个不同类型的产品族,符合开闭原则,但代码复杂度较高。

 场景特点:适用于需要创建一组相关的对象,且这些对象之间存在一定的依赖关系或约束条件的场景。

具体应用:
例1:创建不同风格的 UI 组件
。比如根据不同的主题创建一组相关的UI组件。

// ui-theme-factory.js
// 产品族 class Button { render() { throw new Error("该方法必须被重写!"); } } class LightButton extends Button { render() { console.log("LightButton"); } } class DarkButton extends Button { render() { console.log("DarkButton"); } }
// 产品族 class Input { render() {
throw new Error("该方法必须被重写!"); } } class LightInput extends Input { render() { console.log("LightInput"); } } class DarkInput extends Input { render() { console.log("DarkInput"); } } class ThemeFactory { createButton() { throw new Error("该方法必须被重写!"); } createInput() { throw new Error("该方法必须被重写!"); } } class LightThemeFactory extends ThemeFactory { createButton() { return new LightButton(); } createInput() { return new LightInput(); } } class DarkThemeFactory extends ThemeFactory { createButton() { return new DarkButton(); } createInput() { return new DarkInput(); } } const lightFactory = new LightThemeFactory(); const lightButton = lightFactory.createButton(); const lightInput = lightFactory.createInput(); lightButton.render(); // LightButton lightInput.render(); // LightInput

例2:游戏中创建不同风格的游戏场景。比如沙漠场景、森林场景等。每个场景都有一组相关的游戏元素,如地形、怪物、道具等。

 代码逻辑差不多,就不实现了。

四、如何选择

从上文中可以得出以下结论:

 1、从适用场景考虑

简单工厂模式:产品种类较少,且不经常扩展

工厂方法模式:产品种类较多,需要频繁扩展

抽象工厂模式:需要同时创建多个关联产品

2、从产品类型和关联关系考虑

简单工厂模式:创建单一类型的对象,产品之间没有复杂的关联关系,只是根据不同的参数创建不同具体实现的对象。

工厂方法模式:侧重于创建单一类型的对象,方便扩展新的产品类型,产品之间相对独立,没有紧密的依赖关系。

抽象工厂模式:创建一组相关的对象,这些对象构成一个产品族,它们之间存在内在的关联和依赖关系。需要保证在同一产品族中的对象是相互兼容的。

3、从代码复杂度和维护成本考虑

简单工厂模式:代码结构简单,实现成本低,但当产品类型增多时,工厂类会变得臃肿,不符合开闭原则,维护成本会逐渐增加。

工厂方法模式:代码复杂度适中,通过将创建逻辑分散到具体的工厂子类中,提高了代码的可维护性和可扩展性,新增产品时对现有代码的影响较小。

抽象工厂模式:代码复杂度较高,需要定义多个抽象类和具体类,但它提供了更高层次的抽象和封装,能够很好地处理复杂的产品族创建问题,在复杂项目中可以有效降低整体的维护成本。