北京官方网站网,云梦网络做网站,个人免费发布信息平台,网站建设亿金手指花总12作为前端开发#xff0c;在code时#xff0c;或多或少地都会践行设计模式#xff0c;但是你清楚自己用到的是何种设计模式吗#xff1f;
为什么前端开发一定要懂设计模式呢#xff1f;
code时不遵从设计模式#xff0c;又能怎样呢#xff1f;
上面的问题可以留作思考…作为前端开发在code时或多或少地都会践行设计模式但是你清楚自己用到的是何种设计模式吗
为什么前端开发一定要懂设计模式呢
code时不遵从设计模式又能怎样呢
上面的问题可以留作思考这里首先介绍一下前端开发经常遇到的一些设计模式和设计原则。
前端常见的设计模式
1 单例模式
在整个应用程序中只允许创建一个实例的模式。 在前端开发中它通常用于管理全局状态或资源例如 在 React 应用中使用 Redux 库来管理应用的状态在 Vue 应用中使用 Vuex 库来管理应用的状态在 Angular 应用中使用 Service 来管理应用的状态 angular 服务是可注入的类用于提供共享的数据、功能或逻辑给整个应用程序的组件由于服务是以单例形式存在的每次注入服务都会返回同一个实例。
使用Injectable({ providedIn: root })装饰器将MyService注册为根级提供商这意味着整个应用程序都可以访问该服务的单一实例。
// my.service.tsimport { Injectable } from angular/core;Injectable({providedIn: root
})export class MyService {private count: number 0;incrementCount() {this.count;}getCount(): number {return this.count;}
}
在组件中可以通过依赖注入的方式来使用该服务
// my.component.tsimport { Component } from angular/core;
import { MyService } from ./my.service;Component({selector: my-component,template: h2Count: {{ myService.getCount() }}/h2button (click)incrementCount()Increment Count/button
})
export class MyComponent {constructor(private myService: MyService) {}incrementCount() {this.myService.incrementCount();}
}
拓展 如果在Angular中的Injectable装饰器的providedIn配置中不使用root而是指定其他模块或组件那么该服务将在该模块或组件的范围内成为单例。 这意味着服务将在指定的模块或组件及其子组件中共享同一个实例而不是在整个应用程序中共享。这对于需要在特定范围内共享数据或功能的场景非常有用。 例如假设有两个组件ComponentA和ComponentB它们都引用了同一个服务SharedService并且将该服务作为提供程序配置在它们各自的模块中。
// shared.service.tsimport { Injectable } from angular/core;Injectable({providedIn: other-module // 指定其他模块而不是 root
})
export class SharedService {public sharedData: string Shared data;
}
// component-a.component.tsimport { Component } from angular/core;
import { SharedService } from ./shared.service;Component({selector: component-a,template: h2{{ sharedService.sharedData }}/h2
})
export class ComponentA {constructor(public sharedService: SharedService) {}
}
// component-b.component.tsimport { Component } from angular/core;
import { SharedService } from ./shared.service;Component({selector: component-b,template: h2{{ sharedService.sharedData }}/h2
})
export class ComponentB {constructor(public sharedService: SharedService) {}
}
在这种情况下SharedService将在ComponentA和ComponentB之间共享同一个实例但其作用范围限定在这两个组件及其子组件中。
这种用法可以让开发者更细粒度地控制服务的共享范围使得不同的模块或组件可以拥有各自独立的服务实例。
2 观察者模式
2.1 Vue.js
针对前端的观察者模式一种常见的应用是使用Vue.js框架的响应式系统。Vue.js使用观察者模式来追踪数据的变化并更新视图。
!-- index.html --!DOCTYPE html
html
headtitleVue.js Observer Example/titlescript srchttps://unpkg.com/vue2.6.14/dist/vue.js/script
/head
bodydiv idapph2{{ message }}/h2input v-modelmessage typetext placeholderType something.../divscript// Initialize Vuenew Vue({el: #app,data: {message: Hello, Vue!}});/script
/body
/html
上述代码中使用了Vue.js来创建一个具有双向数据绑定的简单应用。message属性的值将被显示在页面上的 h2 标签中并且可以通过输入框进行编辑。
Vue.js的响应式系统会在message属性发生变化时自动更新页面中对应的内容。这是通过Vue.js在内部使用观察者模式来实现的。当message属性的值发生变化时观察者会被通知并执行相应的更新。
这种观察者模式的应用使得开发者无需显式地修改DOM来更新视图而是只需关注数据的变化Vue.js会自动处理更新过程。这大大简化了前端开发中处理视图更新的任务。
2.2 Angular
在Angular中观察者模式主要通过使用RxJS响应式扩展库来实现。RxJS是一个强大的事件处理库它提供了多种操作符和观察者模式的实现以处理异步事件流。
在Angular中通过使用Observables可观察对象和Subjects主题开发者可以实现观察者模式的效果并在组件之间进行事件通信或数据共享。
下面是一个简单的示例展示了如何在Angular中使用观察者模式实现组件之间的通信
// message.service.tsimport { Injectable } from angular/core;
import { Subject } from rxjs;Injectable()
export class MessageService {private messageSubject new Subjectstring();message$ this.messageSubject.asObservable();sendMessage(message: string) {this.messageSubject.next(message);}
}
上述代码创建了一个名为MessageService的服务它使用Subject创建了一个消息主题。通过调用主题的next()方法可以向订阅该主题的观察者发送消息。
// component-a.component.tsimport { Component } from angular/core;
import { MessageService } from ./message.service;Component({selector: component-a,template: button (click)sendMessage()Send Message/button
})
export class ComponentA {constructor(private messageService: MessageService) {}sendMessage() {this.messageService.sendMessage(Hello from Component A!);}
}
上述代码创建了一个名为ComponentA的组件它通过依赖注入的方式引用了MessageService。在按钮的点击事件中我们调用sendMessage()方法来发送一条消息。
// component-b.component.tsimport { Component } from angular/core;
import { MessageService } from ./message.service;Component({selector: component-b,template: h2{{ receivedMessage }}/h2
})
export class ComponentB {receivedMessage: string ;constructor(private messageService: MessageService) {}ngOnInit() {this.messageService.message$.subscribe(message {this.receivedMessage message;});}
}
上述代码创建了一个名为ComponentB的组件并在ngOnInit()生命周期钩子中订阅了MessageService的message$可观察对象。一旦有新的消息发送观察者将接收到该消息并更新receivedMessage属性。
使用上述代码当ComponentA中的按钮被点击时它将向ComponentB发送一条消息并在ComponentB中更新显示的消息。这通过观察者模式实现组件之间的双向通信。
2.3 React
在 React 中观察者模式可以通过使用 Context API 和钩子函数来实现。下面是一个简单的示例
首先创建一个观察者上下文ObserverContext
import React, { createContext, useContext, useState } from react;const ObserverContext createContext();export const ObserverProvider ({ children }) {const [observers, setObservers] useState([]);const addObserver (observer) {setObservers((prevObservers) [...prevObservers, observer]);};const removeObserver (observer) {setObservers((prevObservers) prevObservers.filter((o) o ! observer));};const notifyObservers () {observers.forEach((observer) observer());};const contextValue {addObserver,removeObserver,notifyObservers,};return (ObserverContext.Provider value{contextValue}{children}/ObserverContext.Provider);
};export const useObserver (observer) {const { addObserver, removeObserver } useContext(ObserverContext);// 添加观察者useEffect(() {addObserver(observer);// 组件卸载时移除观察者return () removeObserver(observer);}, [observer, addObserver, removeObserver]);
};
然后在需要进行观察的组件中使用 useObserver 钩子来订阅和响应变化。
import React, { useState } from react;
import { useObserver } from ./ObserverContext;const Counter () {const [count, setCount] useState(0);const handleIncrement () {setCount((prevCount) prevCount 1);};// 添加观察者useObserver(() {console.log(Count has changed:, count);});return (divpCount: {count}/pbutton onClick{handleIncrement}Increment/button/div);
};
在上述示例中ObserverProvider 提供了观察者的上下文并定义了添加观察者、移除观察者和通知观察者的方法。使用 useObserver 钩子来订阅观察者模式中的变化。当状态这里是 count发生变化时观察者将被通知并执行相应的操作。
使用这种方式可以在 React 中实现简单的观察者模式以便组件之间能够订阅和响应特定的事件或状态变化。
3 代码工厂模式
代码工厂模式是一种创建对象的设计模式它通过使用工厂函数或类来封装对象的创建过程。在这种模式下我们不直接调用对象的构造函数来创建对象而是通过一个专门的工厂方法来统一管理对象的创建。
代码工厂模式的主要目的是隐藏具体对象创建的细节并提供一种可扩展和灵活的方式来创建对象。它将对象的实例化逻辑封装在一个独立的组件中使得创建对象的过程可以进行集中管理而不是分散在应用程序的各个地方。
3.1 Angular
下面是一个简单的示例展示了如何在 Angular 中使用代码工厂模式
import { Injectable } from angular/core;Injectable({providedIn: root,
})
export class UserService {private users: string[] [];addUser(user: string): void {this.users.push(user);}getUsers(): string[] {return this.users;}
}Injectable({providedIn: root,
})
export class UserFactory {constructor(private userService: UserService) {}createUser(name: string): void {this.userService.addUser(name);}
}在上述示例中UserService 是一个服务类它管理用户信息。UserFactory 是一个工厂类负责创建用户并将其添加到 UserService 中。
在 Angular 中通过使用 Injectable() 装饰器和 providedIn: root 选项我们可以将 UserService 和 UserFactory 注册为可注入的服务并确保它们在整个应用程序中的任何组件中都可用。
然后在其他组件中可以通过依赖注入的方式使用这些服务
import { Component } from angular/core;
import { UserFactory } from ./user.factory;Component({...})
export class AppComponent {constructor(private userFactory: UserFactory) {}createUser() {this.userFactory.createUser(John);}
}
在上述示例中AppComponent 组件通过依赖注入 UserFactory 来使用工厂模式创建用户。
通过在 Angular 中使用代码工厂模式我们可以将对象的创建和初始化逻辑封装到可注入的服务中并在需要时利用依赖注入方便地使用这些服务。这样可以提高代码的可维护性、扩展性和测试性。
3.2 React
下面是一个简单的示例展示了如何在 React 中使用代码工厂模式
import React from react;// 工厂函数
function createButton(type) {const Button (props) {let button;if (type primary) {button (button classNameprimary-button onClick{props.onClick}{props.children}/button);} else if (type secondary) {button (button classNamesecondary-button onClick{props.onClick}{props.children}/button);} else {throw new Error(Invalid button type);}return button;};return Button;
}// 使用工厂函数创建按钮组件
const PrimaryButton createButton(primary);
const SecondaryButton createButton(secondary);// 使用按钮组件
const App () (divPrimaryButton onClick{() console.log(Primary button clicked)}Primary Button/PrimaryButtonSecondaryButton onClick{() console.log(Secondary button clicked)}Secondary Button/SecondaryButton/div
);
在上述例子中createButton 是一个工厂函数根据传入的 type 参数返回一个特定类型的按钮组件。根据不同的类型创建不同样式、行为或功能的按钮。
通过调用 createButton 工厂函数可以轻松创建不同类型的按钮组件并在应用程序中使用它们。这样避免在多个地方重复编写相似的代码而是通过工厂模式集中管理和创建组件。
使用工厂模式可以根据需要快速创建并定制化多个组件并轻松地进行修改或扩展。这种模式提供了一种更灵活、可维护和可重用的方式来创建和管理 React 组件。
4 策略模式
策略模式用于定义一系列算法并将其封装成独立的对象使它们可以相互替换。在前端开发中策略模式可以用来处理多种算法或逻辑的情况例如在表单验证中根据不同规则进行验证。
下面是一个简单的示例用于根据不同的排序策略对数组进行排序
// 排序策略对象
const sortingStrategies {quickSort: (arr) arr.sort((a, b) a - b),mergeSort: (arr) arr.sort((a, b) b - a),
};// 排序上下文对象
class SortContext {constructor(strategy) {this.strategy strategy;}setStrategy(strategy) {this.strategy strategy;}sort(arr) {return this.strategy(arr);}
}// 使用策略模式进行排序
const arr [5, 2, 8, 1, 4];
const context new SortContext(sortingStrategies.quickSort);
console.log(context.sort(arr)); // 输出: [1, 2, 4, 5, 8]context.setStrategy(sortingStrategies.mergeSort);
console.log(context.sort(arr)); // 输出: [8, 5, 4, 2, 1]
在上述示例中sortingStrategies 是一个包含不同排序策略的对象其中 quickSort 和 mergeSort 是两种不同的排序算法。
SortContext 是排序上下文对象它接收一个排序策略作为参数并提供 setStrategy 方法来动态更改当前的排序策略。sort 方法使用当前的排序策略对给定的数组进行排序。
通过创建 SortContext 实例并设置不同的排序策略我们可以根据需要选择特定的排序算法对数组进行排序。这样我们可以在运行时根据需求灵活地切换算法而不需要在每个地方都修改排序逻辑。
策略模式使得应用程序更具可扩展性和灵活性因为我们可以轻松添加新的策略或修改现有的策略而无需修改已有的代码。同时它还能提高代码的可读性和可维护性使算法选择与实际执行逻辑分离开来。 文章转载自: http://www.morning.ljtwp.cn.gov.cn.ljtwp.cn http://www.morning.rkfgx.cn.gov.cn.rkfgx.cn http://www.morning.hbfqm.cn.gov.cn.hbfqm.cn http://www.morning.0small.cn.gov.cn.0small.cn http://www.morning.pthmn.cn.gov.cn.pthmn.cn http://www.morning.zstbc.cn.gov.cn.zstbc.cn http://www.morning.ybgt.cn.gov.cn.ybgt.cn http://www.morning.zzfjh.cn.gov.cn.zzfjh.cn http://www.morning.nmtyx.cn.gov.cn.nmtyx.cn http://www.morning.znqmh.cn.gov.cn.znqmh.cn http://www.morning.smyxl.cn.gov.cn.smyxl.cn http://www.morning.fkflc.cn.gov.cn.fkflc.cn http://www.morning.gfmpk.cn.gov.cn.gfmpk.cn http://www.morning.fwzjs.cn.gov.cn.fwzjs.cn http://www.morning.ffydh.cn.gov.cn.ffydh.cn http://www.morning.dgckn.cn.gov.cn.dgckn.cn http://www.morning.yzktr.cn.gov.cn.yzktr.cn http://www.morning.qtxwb.cn.gov.cn.qtxwb.cn http://www.morning.wdnkp.cn.gov.cn.wdnkp.cn http://www.morning.hmxrs.cn.gov.cn.hmxrs.cn http://www.morning.rkqkb.cn.gov.cn.rkqkb.cn http://www.morning.rwxnn.cn.gov.cn.rwxnn.cn http://www.morning.yzygj.cn.gov.cn.yzygj.cn http://www.morning.mrqwy.cn.gov.cn.mrqwy.cn http://www.morning.rlksq.cn.gov.cn.rlksq.cn http://www.morning.mnwsy.cn.gov.cn.mnwsy.cn http://www.morning.kjyhh.cn.gov.cn.kjyhh.cn http://www.morning.qytby.cn.gov.cn.qytby.cn http://www.morning.kxbry.cn.gov.cn.kxbry.cn http://www.morning.eshixi.com.gov.cn.eshixi.com http://www.morning.kncrc.cn.gov.cn.kncrc.cn http://www.morning.txlnd.cn.gov.cn.txlnd.cn http://www.morning.xbmwm.cn.gov.cn.xbmwm.cn http://www.morning.huihuangwh.cn.gov.cn.huihuangwh.cn http://www.morning.nlmm.cn.gov.cn.nlmm.cn http://www.morning.tndhm.cn.gov.cn.tndhm.cn http://www.morning.xhpnp.cn.gov.cn.xhpnp.cn http://www.morning.jrpmf.cn.gov.cn.jrpmf.cn http://www.morning.jbpdk.cn.gov.cn.jbpdk.cn http://www.morning.rytps.cn.gov.cn.rytps.cn http://www.morning.fsfz.cn.gov.cn.fsfz.cn http://www.morning.rsnd.cn.gov.cn.rsnd.cn http://www.morning.mqbdb.cn.gov.cn.mqbdb.cn http://www.morning.hdscx.cn.gov.cn.hdscx.cn http://www.morning.rcdmp.cn.gov.cn.rcdmp.cn http://www.morning.brscd.cn.gov.cn.brscd.cn http://www.morning.znqztgc.cn.gov.cn.znqztgc.cn http://www.morning.nspzy.cn.gov.cn.nspzy.cn http://www.morning.xscpq.cn.gov.cn.xscpq.cn http://www.morning.pwgzh.cn.gov.cn.pwgzh.cn http://www.morning.nyzmm.cn.gov.cn.nyzmm.cn http://www.morning.hlshn.cn.gov.cn.hlshn.cn http://www.morning.krywy.cn.gov.cn.krywy.cn http://www.morning.zzfjh.cn.gov.cn.zzfjh.cn http://www.morning.fnywn.cn.gov.cn.fnywn.cn http://www.morning.ltffk.cn.gov.cn.ltffk.cn http://www.morning.pkdng.cn.gov.cn.pkdng.cn http://www.morning.frpfk.cn.gov.cn.frpfk.cn http://www.morning.lbpfl.cn.gov.cn.lbpfl.cn http://www.morning.zstry.cn.gov.cn.zstry.cn http://www.morning.nmwgd.cn.gov.cn.nmwgd.cn http://www.morning.jhqcr.cn.gov.cn.jhqcr.cn http://www.morning.mkyny.cn.gov.cn.mkyny.cn http://www.morning.hqwtm.cn.gov.cn.hqwtm.cn http://www.morning.krfpj.cn.gov.cn.krfpj.cn http://www.morning.jypqx.cn.gov.cn.jypqx.cn http://www.morning.xltdh.cn.gov.cn.xltdh.cn http://www.morning.zmnyj.cn.gov.cn.zmnyj.cn http://www.morning.jpdbj.cn.gov.cn.jpdbj.cn http://www.morning.bbtn.cn.gov.cn.bbtn.cn http://www.morning.nxrgl.cn.gov.cn.nxrgl.cn http://www.morning.pbksb.cn.gov.cn.pbksb.cn http://www.morning.qkgwz.cn.gov.cn.qkgwz.cn http://www.morning.cwyrp.cn.gov.cn.cwyrp.cn http://www.morning.dpgdj.cn.gov.cn.dpgdj.cn http://www.morning.ndtmz.cn.gov.cn.ndtmz.cn http://www.morning.lfdzr.cn.gov.cn.lfdzr.cn http://www.morning.xjpnq.cn.gov.cn.xjpnq.cn http://www.morning.bpmnj.cn.gov.cn.bpmnj.cn http://www.morning.tdscl.cn.gov.cn.tdscl.cn