Aplicación integral de patrones de diseño de JavaScript

1. Introducción

1.1 Carrito de compras de aplicaciones completo

  • 使用 jQuery 做一个模拟购物车的示例
  • 包括:显示购物列表、加入购物车、从购物车删除

1.2 Patrones de diseño utilizados

  • Modo de fábrica, modo singleton
  • Modo decorador, modo observador
  • Modo de estado, modo de método de plantilla, modo de agente

2. Diagrama de clases UML

Inserte la descripción de la imagen aquí

3. Implementación del código

  • App.js
import $ from 'jquery'
import ShoppingCart from './ShoppingCart/ShoppingCart.js'
import List from './List/List.js'

export default class App {
    
    
	constructor(id) {
    
    
		this.$el = $('#' + id)
	}

	// 初始化购物车
	initShoppingCart() {
    
    
		let shoppingCart = new ShoppingCart(this)
		shoppingCart.init()
	}

	// 初始化列表
	initList() {
    
    
		let list = new List(this)
		list.init()
	}

	init() {
    
    
		this.initShoppingCart()
		this.initList()
	}
}
  • ShoppingCart.js
import $ from 'jquery'
import getCart from './GetCart.js'

export default class ShoppingCart {
    
    
	constructor(app) {
    
    
		this.app = app
		this.$el = $('<div>').css({
    
    
			'padding-bottom': '10px',
			'border-bottom': '1px solid #ccc'
		})
		this.cart = getCart()
	}

	initBtn() {
    
    
		let $btn = $('<button>购物车</button>')
		$btn.click(() => {
    
    
			this.showCart()
		})
		this.$el.append($btn)
	}

	showCart() {
    
    
		alert(this.cart.getList())
	}

	render() {
    
    
		this.app.$el.append(this.$el)
	}

	init() {
    
    
		this.initBtn()
		this.render()
	}
}
  • GetCart.js
class Cart {
    
    
	constructor() {
    
    
		this.list = []
	}
	add(data) {
    
    
		this.list.push(data)
	}
	del(id) {
    
    
		this.list = this.list.filter(item => {
    
    
			if (item.id === id) {
    
    
				return false
			}
			return true
		})
	}
	getList() {
    
    
		return this.list.map(item => {
    
    
			return item.name
		}).join('\n')
	}
}

// 返回单例
let getCart = (function () {
    
    
	let cart
	return function () {
    
    
		if (!cart) {
    
    
			cart = new Cart()
		}
		return cart
	}
})()

export default getCart
  • List.js
import $ from 'jquery'
import {
    
     GET_LIST } from '../config/config.js'

export default class List {
    
    
	constructor(app) {
    
    
		this.app = app
		this.$el = $('<div>')
	}

	// 获取数据
	loadData() {
    
    
		// 返回 Promise 实例
		return fetch(GET_LIST).then(result => {
    
    
			return result.json()
		})
	}

	// 生成列表
	initItemList(data) {
    
    
		// data.map(itemData => {
    
    
			// 创建一个 Item 然后 init
			// let item = createItem(this, itemData)
			// item.init()
			// return item
		// }

		data.forEach(itemData => {
    
    
			// 创建一个 Item 然后 init
			let item = createItem(this, itemData)
			item.init()
		}
	}

	// 渲染
	render() {
    
    
		this.app.$el.append(this.$el)
	}

	init() {
    
    
		this.loadData().then(data => {
    
    
			this.initItemList(data)
		}).then(() => {
    
    
			// 渲染
			this.render()
		})
	}
}
  • item.js
import $ from 'jquery'
import getCart from '../ShoppingCart/GetCart.js'
import StateMachine from 'javascript-state-machine'
import {
    
     log } from '../util/log.js'

export default class Item {
    
    
	constructor(list, data) {
    
    
		this.list = list
		this.data = data
		this.$el = $('<div>')
		this.cart = getCart()
	}

	initContent() {
    
    
		let $el = this.$el
		let data = this.data
		$el.append($(`<p>名称: ${
      
      data.name}</p>`))
		$el.append($(`<p>价格: ${
      
      data.price}</p>`))
	}

	initBtn() {
    
    
		let $el = this.$el
		let $btn = $('<button>test</button>')

		let _this = this
		let fsm = new StateMachine({
    
    
			init: '加入购物车',
			transitions: [
				{
    
    
					name: 'addToCart',
					from: '加入购物车',
					to: '从购物车删除'
				},
				{
    
    
					name: 'deleteFromCart'from: '从购物车删除',
					to: '加入购物车'
				}
			],
			methods: {
    
    
				// 加入购物车
				onAddToCart: function () {
    
    
					_this.addToCartHandle
				}
				// 从购物车删除
				onDeleteFromCart: function () {
    
    
					_this.deleteFromCartHanel()
					updateText()
				}
			}
		})
		
		function updateText() {
    
    
			$btn.text(fsm.state)
		}
	
		$btn.click(() => {
    
    
			// 添加到购物车
			// 从购物车移除
			if (fsm.is('加入购物车')) {
    
    
				fsm.addToCart()
			} else {
    
    
				fsm.deleteFromCart()
			}
		})
		updateText()
		$el.append($btn)
	}

	// 添加到购物车
	@log('add')
	addToCartHandle() {
    
    
		this.cart.add(this.data)
	}

	// 从购物车删除
	@log('del')
	deleteFromCartHanel() {
    
    
		this.cart.del(this.data.id)
	}
	
	render() {
    
    
		this.list.$el.append(this.$el)
	}
	
	init() {
    
    
		this.initContent()
		this.initBtn()
		this.render()
	}
}
  • CreateItem.js
import Item from './Item.js'

function createDiscount(itemData) {
    
    
	// 用代理做折扣显示
	return new Proxy(itemData, {
    
    
		get: function (target, key, receiver) {
    
    
			if (key === 'name') {
    
    
				return `${
      
      target[key]}【折扣】`
			}
			if (key === 'price') {
    
    
				return target[key] * 0.8
			}
			return target[key]
		}
	})
}

// 工厂函数
export default function (list, itemData) {
    
    
	if (itemData.discount) {
    
    
		itemData = createDiscount(itemData)
	}
	return new Item(list, itemData)
}
  • config.js
export const GET_LIST = '/api/list.json'
  • list.json
[
	{
    
    
		"id": 1,
		"name": "《JS 面试题》",
		"price": 149,
		"discount": 1
	},
	{
    
    
		"id": 2,
		"name": "《JS 高级面试题》",
		"price": 366,
		"discount": 1
	},
	{
    
    
		"id": 3,
		"name": "《React 模拟大众点评 webapp》",
		"price": 248,
		"discount": 0
	},
	{
    
    
		"id": 4,
		"name": "《zepto 设计与源码解读》",
		"price": 0,
		"discount": 0
	}
]
  • log.js
export function log(type) {
    
    
	return function (target, name, descriptor) {
    
    
		let oldValue = descriptor.value

		descriptor.value = function () {
    
    
			// 在此统一打印日志
			console.log(`日志上报 ${
      
      type}`)
			// 执行原有的方法
			return oldValue.apply(this, arguments)
		}
		
		return descriptor
	}
}

4. Resumen de la aplicación integral

  • 工厂模式
    • $('xxx') Crea un producto
  • 单例模式
    • Carro de compras
  • 装饰器模式
    • Estadísticas de carreras impulsadas
  • 观察者模式
    • La página es falsa, lo prometo
  • 状态模式
    • Agregar al carrito y quitar del carrito
  • 模版方法模式
    • Hay un método unificado de renderizado y se incluye el renderizado interno de cada módulo.
  • 代理模式
    • Procesamiento de información de productos con descuento

Supongo que te gusta

Origin blog.csdn.net/qq_43645678/article/details/115053209
Recomendado
Clasificación