- 设计模式是我们在解决问题的时候,针对特定问题给出的优化处理方案
- 在JS设计模式中,最核心的思想:封装变化
- 将变与不变分离,确保变化的部分灵活,不变的部分稳定
常用设计模式:单例、工厂、抽象工厂、发布-订阅、代理、适配器等等
以下讲了10种:
- 构造器模式
- 原型模式
- 工厂模式
- 抽象工厂模式
- 建造者模式
- 单例模式
- 装饰器模式
- 适配器模式
- 策略模式
- 代理模式
1、构造器模式
var employee = {
name:'李雷',
age:18
}
var employee2 = {
name:'韩梅梅',
age:19
}
以上写法,如果数据量变多,代码重复且臃肿。
function Employee(name,age){
this.name = name;
this.age = age;
this.say = function(){
console.log(this.name+'--'+this.age)
}
}
new Employee('唐三',18)
new Employee('小舞',16)
缺点: say方法都是一样的,每次创建都会重新创建。通过原型解决
2、原型模式
function Employee(name,age){
this.name = name;
this.age = age;
}
Employee.prototype.say = function(){
console.log(this.name+'--'+this.age)
}
new Employee('唐三',18)
new Employee('小舞',16)
用类的方式实现:
class Employee{
constructor(name,age){
this.name = name;
this.age = age;
}
say(){
console.log(this.name+'--'+this.age)
}
}
const employee = new Employee('商璃',17)
employee.say()
一个示例(Tab切换):
function Tabs(selector){ // 参数:CSS选择器
this.selector = document.querySelector(selector)
this.headerItems = this.selector.querySelectorAll('.header li')
this.boxItems = this.selector.querySelectorAll('.box li')
}
Tabs.prototype.change = function(){
for(let i = 0;i<this.headerItems.length;i++){
this.headerItems[i].onClick = ()=>{
for(let m = 0;m<this.headerItems.length;m++){
this.headerItems[m].classList.remove('active')
this.boxItems[m].classList.remove('active')
}
this.headerItems[i].classList.add('active')
this.boxItems[i].classList.add('active')
}
}
}
new Tabs('.container')
3、工厂模式
由一个工厂对象决定创建某一种产品对象的实例。主要用来创建同一类对象。
function UserFactory(role){
function User(role,pages){
this.role = role
this.pages = pages
}
switch(role){
case "superadmin":
return new User('superadmin',['home','user-manage','right-manage','news-manage'])
case "admin":
return new User('admin',['home','right-manage','news-manage'])
case "editor":
return new User('editor',['home','news-manage'])
default:
throw new Error('参数错误')
}
}
简单工厂的优点在于:只需一个正确的参数就可以获取到需要的对象,而无需知道其创建的具体细节。
但是,在函数内包含了所有对象的创建、判断逻辑,每增加新的构造函数还需要修改判断逻辑代码。
当对象变得更多时,这个函数就会成为庞大的超级函数,变得难以维护。
所以,简单工厂只能作用于:创建的对象数量较少、对象创建逻辑不复杂的时候。
4、抽象工厂模式
抽象工厂模式并不直接生成实例,而是用于对产品类的创建
class User{
constructor(name,role,pages){
this.name = name
this.role = role
this.pages = pages
}
welcome(){
console.log('欢迎回来',this.name)
}
dataShow(){
throw new Error('抽象方法不允许直接调用')
}
}
class SuperAdmin extends User{
constructor(name){
super(name,'superadmin',['home','user-manage','right-manage','news-manage'])
}
dataShow(){
console.log('superadmin-datashow')
}
addRight(){
...
}
}
class Admin extends User{
constructor(name){
super(name,'admin',['home','right-manage','news-manage'])
}
dataShow(){
console.log('admin-datashow')
}
addRight(){
...
}
}
class Editor extends User{
constructor(name){
super(name,'editor',['home','news-manage'])
}
dataShow(){
console.log('editor-datashow')
}
addNews(){
...
}
}
function getAstractUserFactory(role){
switch(role){
case "superadmin":
return SuperAdmin
case "admin":
return Admin
case "editor":
return Editor
default:
throw new Error('参数错误')
}
}
let UserClass = getAstractUserFactory('editor')
let user = new UserClass('Lili')
5、建造者模式
建造者模式(builder pattern)属于创建型模式的一种,提供一种创建复杂对象的方式。
它将一个复杂对象的创建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式是一步一步地创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要指定内部的具体构造细节。
class Navbar{
init(){
console.log("navbar-init")
}
getData(){
return new Promise((resolve)=>{
setTimeout(()=>{
resolve();
console.log("navbar-getdata")
},1000)
})
}
render(){
console.log('navbar-rendar')
}
}
class Creator{
async startBuild(builder){
await builder.init()
await builder.getData()
await builder.render()
}
}
const op = new Creator()
op.startBuild(new Navbar())
建造者模式将一个复杂对象的构建层与其表示层相互分离。
工厂模式主要是为了创建对象实例或者类簇(抽象工厂),关心的是最终产出的是什么,而不关系创建的过程。
建造者模式关心的是创建这个对象的整个过程,甚至于创建对象的每一个细节。
6、单例模式
- 保证一个类仅有一个实例,并提供一个访问它的全局访问点
- 主要解决一个全局使用的类频繁地创建和销毁,占用内存
闭包的方式
var Singleton = (function(){
var instance
function User(name,age){
this.name = name;
this.age = age
}
return function(){
if(!instance){
// 创建实例
instance = new User('lili',20)
}
return instance
}
})()
class的方式
class Singleton{
constructor(name,age){
if(!Singleton.instance){
this.name = name
this.age = age
Singleton.instance = this
}
return Singletom.instance
}
}
const singleton = new Singleton('lili',20)
一个示例(Modal 弹窗)
const Modal = (function(){
let instance = null;
return function(){
if(!instance){
instance = document.createElement("div")
instance.innerHTML = '对话框'
instance.className = 'cx'
instance.style.display = 'none'
document.body.appendChild(instance)
}
return instance
}
})()
7、装饰器模式
装饰器模式能够很友好的对已有功能进行拓展,这样不会更改原有的代码、对其他的业务产生影响,方便在较少的改动下对软件功能进行拓展。
Function.prototype.before = function(beforeFn){
var _this = this;
return function(){
beforeFn.apply(this,arguments)
return _this.apply(this,arguments)
}
}
Function.prototype.after = function(afterFn){
var _this = this;
return function(){
const res = _this.apply(this,arguments)
afterFn.apply(this,arguments)
return res
}
}
function test (){
console.log('test')
}
var test1 = test.before(()=>{
console.log('before test')
}).after(()=>{
console.log('after test')
})
test1()
8、适配器模式
将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作。
class TencentMap{
show(){
console.log('开始渲染。。。')
}
}
class BaiduMap{
display(){
console.log('开始渲染Baidu')
}
}
class BaiduMapAdapter extends BaiduMap{
constructor(){
super()
}
show(){
this.display()
}
}
function renderMap(map){
map.show()
}
renderMap(new TencentMap())
renderMap(new BaiduMap())
9、策略模式
策略模式定义了一些列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响使用算法的客户。
策略模式属于对象行为模式,他通过对算法进行封装,把使用算法的责任和算法的实现分隔开,并委派给不同的对象对这些算法进行管理。
该模式主要解决在有多种算法相似的情况下,使用if…else所带来的复杂和难以维护。
它的优点是算法可以自由切换,同时可以避免多重if…else判断,且具有良好的扩展性。
let strategry = {
"A":(salary)=>{
return salary * 4
},
"B":(salary)=>{
return salary * 3
},
"C":(salary)=>{
return salary * 2
}
}
function calBonus(level,salary){
return strategry[level](salary)
}
calBonus("A",10000)
calBonus("C",8000)
10、代理模式
代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问。
代理模式使得代理对象控制具体对象的引用。代理几乎可以是任何对象:文件、资源、内存中的对象或者一些难以复制的东西。
let obj = {}
let proxy = new Proxy(obj,{
get(target,key){
console.log('get',target[key])
return target[key]
},
set(target,key,value){
if(key==='data'){
box.innerHTML = value
}
target[key]= value
}
})
设计模式是软件开发中的经验总结,本文详细介绍了10种常见设计模式:构造器、原型、工厂、抽象工厂、建造者、单例、装饰器、适配器、策略和代理模式。通过实例和优缺点分析,帮助开发者更好地理解和运用这些模式,提升代码的可维护性和扩展性。
164

被折叠的 条评论
为什么被折叠?



