JavaScript 设计模式 -- 综合应用

JavaScript 设计模式 ---- 综合应用

    • 1. 介绍
        • 1.1 综合应用 -- 购物车
        • 1.2 运用到的设计模式
    • 2. UML 类图
    • 3. 代码实现
    • 4. 综合应用总结

1. 介绍

1.1 综合应用 – 购物车

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

1.2 运用到的设计模式

  • 工厂模式、单例模式
  • 装饰器模式、观察者模式
  • 状态模式、模板方法模式、代理模式

2. UML 类图

JavaScript 设计模式 -- 综合应用_第1张图片

3. 代码实现

  • 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 = $('
').css({ 'padding-bottom': '10px', 'border-bottom': '1px solid #ccc' }) this.cart = getCart() } initBtn() { let $btn = $('') $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 = $('
') } // 获取数据 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 = $('
') this.cart = getCart() } initContent() { let $el = this.$el let data = this.data $el.append($(`

名称: ${data.name}

`
)) $el.append($(`

价格: ${data.price}

`
)) } initBtn() { let $el = this.$el let $btn = $('') 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. 综合应用总结

  • 工厂模式
    • $('xxx') 创建商品
  • 单例模式
    • 购物车
  • 装饰器模式
    • 打点统计
  • 观察者模式
    • 网页是假, Promise
  • 状态模式
    • 添加到购物车 & 从购物车删除
  • 模版方法模式
    • 渲染有统一的方法,内部包含了各模块渲染
  • 代理模式
    • 打折商品信息处理

你可能感兴趣的:(#,JS,设计模式,设计模式,js,JavaScript,设计模式,设计模式应用)