发布于

前端架构模式深度解析:MVC、MVVM到现代组件化架构

作者

前端架构模式深度解析:MVC、MVVM到现代组件化架构

前端架构模式的演进反映了Web应用复杂度的不断提升。本文将深入探讨各种架构模式的设计理念、实现方式和适用场景。

传统架构模式

MVC模式 (Model-View-Controller)

// MVC模式实现
class Model {
  constructor() {
    this.data = {}
    this.observers = []
  }
  
  // 添加观察者
  addObserver(observer) {
    this.observers.push(observer)
  }
  
  // 移除观察者
  removeObserver(observer) {
    const index = this.observers.indexOf(observer)
    if (index > -1) {
      this.observers.splice(index, 1)
    }
  }
  
  // 通知观察者
  notifyObservers(change) {
    this.observers.forEach(observer => {
      observer.update(change)
    })
  }
  
  // 设置数据
  set(key, value) {
    const oldValue = this.data[key]
    this.data[key] = value
    
    this.notifyObservers({
      type: 'set',
      key,
      oldValue,
      newValue: value
    })
  }
  
  // 获取数据
  get(key) {
    return this.data[key]
  }
  
  // 获取所有数据
  getAll() {
    return { ...this.data }
  }
}

// 用户模型
class UserModel extends Model {
  constructor() {
    super()
    this.data = {
      users: [],
      currentUser: null,
      loading: false,
      error: null
    }
  }
  
  async fetchUsers() {
    this.set('loading', true)
    this.set('error', null)
    
    try {
      const response = await fetch('/api/users')
      const users = await response.json()
      this.set('users', users)
    } catch (error) {
      this.set('error', error.message)
    } finally {
      this.set('loading', false)
    }
  }
  
  async createUser(userData) {
    this.set('loading', true)
    
    try {
      const response = await fetch('/api/users', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(userData)
      })
      
      const newUser = await response.json()
      const users = [...this.get('users'), newUser]
      this.set('users', users)
      
      return newUser
    } catch (error) {
      this.set('error', error.message)
      throw error
    } finally {
      this.set('loading', false)
    }
  }
  
  setCurrentUser(user) {
    this.set('currentUser', user)
  }
}

// 视图类
class View {
  constructor(element) {
    this.element = element
    this.controller = null
  }
  
  setController(controller) {
    this.controller = controller
  }
  
  render(data) {
    throw new Error('render method must be implemented')
  }
  
  update(change) {
    // 响应模型变化
    this.render(change)
  }
}

// 用户列表视图
class UserListView extends View {
  constructor(element) {
    super(element)
    this.setupEventListeners()
  }
  
  setupEventListeners() {
    // 添加用户按钮
    const addButton = this.element.querySelector('#add-user-btn')
    if (addButton) {
      addButton.addEventListener('click', () => {
        this.controller.showAddUserForm()
      })
    }
    
    // 刷新按钮
    const refreshButton = this.element.querySelector('#refresh-btn')
    if (refreshButton) {
      refreshButton.addEventListener('click', () => {
        this.controller.refreshUsers()
      })
    }
  }
  
  render(data) {
    const { users, loading, error } = data
    
    if (loading) {
      this.element.innerHTML = '<div class="loading">Loading users...</div>'
      return
    }
    
    if (error) {
      this.element.innerHTML = `<div class="error">Error: ${error}</div>`
      return
    }
    
    const userListHTML = users.map(user => `
      <div class="user-item" data-user-id="${user.id}">
        <div class="user-info">
          <h3>${user.name}</h3>
          <p>${user.email}</p>
        </div>
        <div class="user-actions">
          <button class="edit-btn" data-user-id="${user.id}">Edit</button>
          <button class="delete-btn" data-user-id="${user.id}">Delete</button>
        </div>
      </div>
    `).join('')
    
    this.element.innerHTML = `
      <div class="user-list-header">
        <h2>Users</h2>
        <div class="actions">
          <button id="add-user-btn">Add User</button>
          <button id="refresh-btn">Refresh</button>
        </div>
      </div>
      <div class="user-list">
        ${userListHTML}
      </div>
    `
    
    // 重新绑定事件监听器
    this.setupEventListeners()
    this.setupUserActions()
  }
  
  setupUserActions() {
    // 编辑用户
    this.element.querySelectorAll('.edit-btn').forEach(btn => {
      btn.addEventListener('click', (e) => {
        const userId = e.target.dataset.userId
        this.controller.editUser(userId)
      })
    })
    
    // 删除用户
    this.element.querySelectorAll('.delete-btn').forEach(btn => {
      btn.addEventListener('click', (e) => {
        const userId = e.target.dataset.userId
        this.controller.deleteUser(userId)
      })
    })
  }
}

// 控制器类
class Controller {
  constructor(model, view) {
    this.model = model
    this.view = view
    
    // 设置双向引用
    this.view.setController(this)
    this.model.addObserver(this.view)
    
    this.init()
  }
  
  init() {
    // 初始化加载数据
    this.refreshUsers()
  }
  
  refreshUsers() {
    this.model.fetchUsers()
  }
  
  showAddUserForm() {
    // 显示添加用户表单
    const modal = document.createElement('div')
    modal.className = 'modal'
    modal.innerHTML = `
      <div class="modal-content">
        <h3>Add New User</h3>
        <form id="add-user-form">
          <input type="text" name="name" placeholder="Name" required>
          <input type="email" name="email" placeholder="Email" required>
          <div class="form-actions">
            <button type="submit">Add User</button>
            <button type="button" class="cancel-btn">Cancel</button>
          </div>
        </form>
      </div>
    `
    
    document.body.appendChild(modal)
    
    // 表单提交
    const form = modal.querySelector('#add-user-form')
    form.addEventListener('submit', async (e) => {
      e.preventDefault()
      
      const formData = new FormData(form)
      const userData = {
        name: formData.get('name'),
        email: formData.get('email')
      }
      
      try {
        await this.model.createUser(userData)
        document.body.removeChild(modal)
      } catch (error) {
        alert('Failed to create user: ' + error.message)
      }
    })
    
    // 取消按钮
    modal.querySelector('.cancel-btn').addEventListener('click', () => {
      document.body.removeChild(modal)
    })
  }
  
  editUser(userId) {
    const users = this.model.get('users')
    const user = users.find(u => u.id === userId)
    
    if (user) {
      // 实现编辑用户逻辑
      console.log('Edit user:', user)
    }
  }
  
  deleteUser(userId) {
    if (confirm('Are you sure you want to delete this user?')) {
      // 实现删除用户逻辑
      console.log('Delete user:', userId)
    }
  }
}

// 使用MVC模式
const userModel = new UserModel()
const userListElement = document.getElementById('user-list')
const userListView = new UserListView(userListElement)
const userController = new Controller(userModel, userListView)

MVVM模式 (Model-View-ViewModel)

// MVVM模式实现
class Observable {
  constructor(value) {
    this._value = value
    this._observers = []
  }
  
  get value() {
    return this._value
  }
  
  set value(newValue) {
    if (this._value !== newValue) {
      this._value = newValue
      this._observers.forEach(observer => observer(newValue))
    }
  }
  
  subscribe(observer) {
    this._observers.push(observer)
    
    // 返回取消订阅函数
    return () => {
      const index = this._observers.indexOf(observer)
      if (index > -1) {
        this._observers.splice(index, 1)
      }
    }
  }
}

// 计算属性
class Computed {
  constructor(computeFn, dependencies = []) {
    this.computeFn = computeFn
    this.dependencies = dependencies
    this._value = null
    this._observers = []
    this._isStale = true
    
    // 订阅依赖变化
    this.dependencies.forEach(dep => {
      dep.subscribe(() => {
        this._isStale = true
        this._observers.forEach(observer => observer(this.value))
      })
    })
  }
  
  get value() {
    if (this._isStale) {
      this._value = this.computeFn()
      this._isStale = false
    }
    return this._value
  }
  
  subscribe(observer) {
    this._observers.push(observer)
    
    return () => {
      const index = this._observers.indexOf(observer)
      if (index > -1) {
        this._observers.splice(index, 1)
      }
    }
  }
}

// ViewModel基类
class ViewModel {
  constructor() {
    this.observables = new Map()
    this.computeds = new Map()
    this.bindings = new Map()
  }
  
  // 创建可观察属性
  observable(name, initialValue) {
    const obs = new Observable(initialValue)
    this.observables.set(name, obs)
    return obs
  }
  
  // 创建计算属性
  computed(name, computeFn, dependencies = []) {
    const comp = new Computed(computeFn, dependencies)
    this.computeds.set(name, comp)
    return comp
  }
  
  // 获取属性值
  get(name) {
    if (this.observables.has(name)) {
      return this.observables.get(name).value
    }
    if (this.computeds.has(name)) {
      return this.computeds.get(name).value
    }
    return undefined
  }
  
  // 设置属性值
  set(name, value) {
    if (this.observables.has(name)) {
      this.observables.get(name).value = value
    }
  }
  
  // 绑定到DOM元素
  bind(element) {
    this.bindAttributes(element)
    this.bindEvents(element)
    this.bindContent(element)
  }
  
  bindAttributes(element) {
    // 绑定属性
    Array.from(element.attributes).forEach(attr => {
      if (attr.name.startsWith('v-bind:') || attr.name.startsWith(':')) {
        const propName = attr.name.replace(/^(v-bind:|:)/, '')
        const observableName = attr.value
        
        if (this.observables.has(observableName)) {
          const observable = this.observables.get(observableName)
          
          // 初始设置
          element[propName] = observable.value
          
          // 订阅变化
          observable.subscribe(value => {
            element[propName] = value
          })
        }
      }
    })
  }
  
  bindEvents(element) {
    // 绑定事件
    Array.from(element.attributes).forEach(attr => {
      if (attr.name.startsWith('v-on:') || attr.name.startsWith('@')) {
        const eventName = attr.name.replace(/^(v-on:|@)/, '')
        const methodName = attr.value
        
        if (typeof this[methodName] === 'function') {
          element.addEventListener(eventName, (e) => {
            this[methodName](e)
          })
        }
      }
    })
  }
  
  bindContent(element) {
    // 绑定文本内容
    if (element.hasAttribute('v-text')) {
      const observableName = element.getAttribute('v-text')
      
      if (this.observables.has(observableName)) {
        const observable = this.observables.get(observableName)
        
        element.textContent = observable.value
        observable.subscribe(value => {
          element.textContent = value
        })
      }
    }
    
    // 绑定HTML内容
    if (element.hasAttribute('v-html')) {
      const observableName = element.getAttribute('v-html')
      
      if (this.observables.has(observableName)) {
        const observable = this.observables.get(observableName)
        
        element.innerHTML = observable.value
        observable.subscribe(value => {
          element.innerHTML = value
        })
      }
    }
    
    // 递归绑定子元素
    Array.from(element.children).forEach(child => {
      this.bind(child)
    })
  }
}

// 用户管理ViewModel
class UserManagementViewModel extends ViewModel {
  constructor() {
    super()
    
    // 可观察属性
    this.users = this.observable('users', [])
    this.loading = this.observable('loading', false)
    this.error = this.observable('error', null)
    this.searchTerm = this.observable('searchTerm', '')
    this.newUserName = this.observable('newUserName', '')
    this.newUserEmail = this.observable('newUserEmail', '')
    
    // 计算属性
    this.filteredUsers = this.computed('filteredUsers', () => {
      const users = this.get('users')
      const searchTerm = this.get('searchTerm').toLowerCase()
      
      if (!searchTerm) return users
      
      return users.filter(user => 
        user.name.toLowerCase().includes(searchTerm) ||
        user.email.toLowerCase().includes(searchTerm)
      )
    }, [this.users, this.searchTerm])
    
    this.userCount = this.computed('userCount', () => {
      return this.get('filteredUsers').length
    }, [this.filteredUsers])
    
    this.canAddUser = this.computed('canAddUser', () => {
      const name = this.get('newUserName')
      const email = this.get('newUserEmail')
      return name.trim() && email.trim() && this.isValidEmail(email)
    }, [this.newUserName, this.newUserEmail])
    
    // 初始化
    this.loadUsers()
  }
  
  isValidEmail(email) {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
    return emailRegex.test(email)
  }
  
  async loadUsers() {
    this.set('loading', true)
    this.set('error', null)
    
    try {
      const response = await fetch('/api/users')
      const users = await response.json()
      this.set('users', users)
    } catch (error) {
      this.set('error', error.message)
    } finally {
      this.set('loading', false)
    }
  }
  
  async addUser() {
    if (!this.get('canAddUser')) return
    
    const userData = {
      name: this.get('newUserName'),
      email: this.get('newUserEmail')
    }
    
    this.set('loading', true)
    
    try {
      const response = await fetch('/api/users', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(userData)
      })
      
      const newUser = await response.json()
      const users = [...this.get('users'), newUser]
      this.set('users', users)
      
      // 清空表单
      this.set('newUserName', '')
      this.set('newUserEmail', '')
      
    } catch (error) {
      this.set('error', error.message)
    } finally {
      this.set('loading', false)
    }
  }
  
  deleteUser(userId) {
    const users = this.get('users').filter(user => user.id !== userId)
    this.set('users', users)
  }
  
  // 事件处理方法
  onSearchInput(event) {
    this.set('searchTerm', event.target.value)
  }
  
  onNameInput(event) {
    this.set('newUserName', event.target.value)
  }
  
  onEmailInput(event) {
    this.set('newUserEmail', event.target.value)
  }
  
  onAddUserClick() {
    this.addUser()
  }
  
  onDeleteUserClick(event) {
    const userId = event.target.dataset.userId
    if (confirm('Are you sure you want to delete this user?')) {
      this.deleteUser(userId)
    }
  }
}

// 使用MVVM模式
const viewModel = new UserManagementViewModel()

// 绑定到DOM
document.addEventListener('DOMContentLoaded', () => {
  const app = document.getElementById('app')
  viewModel.bind(app)
  
  // 手动绑定一些复杂的UI更新
  viewModel.filteredUsers.subscribe(users => {
    const userList = document.getElementById('user-list')
    userList.innerHTML = users.map(user => `
      <div class="user-item">
        <div class="user-info">
          <h3>${user.name}</h3>
          <p>${user.email}</p>
        </div>
        <button class="delete-btn" data-user-id="${user.id}" onclick="viewModel.onDeleteUserClick(event)">
          Delete
        </button>
      </div>
    `).join('')
  })
  
  viewModel.loading.subscribe(loading => {
    const loadingElement = document.getElementById('loading')
    loadingElement.style.display = loading ? 'block' : 'none'
  })
  
  viewModel.error.subscribe(error => {
    const errorElement = document.getElementById('error')
    if (error) {
      errorElement.textContent = error
      errorElement.style.display = 'block'
    } else {
      errorElement.style.display = 'none'
    }
  })
})

现代组件化架构

组件系统设计

// 现代组件系统
class Component {
  constructor(props = {}) {
    this.props = props
    this.state = {}
    this.element = null
    this.children = []
    this.parent = null
    this.eventListeners = new Map()
    this.lifecycle = {
      mounted: false,
      destroyed: false
    }
  }
  
  // 生命周期方法
  beforeMount() {}
  mounted() {}
  beforeUpdate() {}
  updated() {}
  beforeDestroy() {}
  destroyed() {}
  
  // 状态管理
  setState(newState) {
    const prevState = { ...this.state }
    this.state = { ...this.state, ...newState }
    
    if (this.lifecycle.mounted) {
      this.beforeUpdate()
      this.update()
      this.updated()
    }
  }
  
  // 渲染方法
  render() {
    throw new Error('render method must be implemented')
  }
  
  // 更新组件
  update() {
    if (!this.element) return
    
    const newElement = this.render()
    
    // 简单的DOM diff和更新
    if (this.element.tagName !== newElement.tagName) {
      this.element.parentNode.replaceChild(newElement, this.element)
      this.element = newElement
    } else {
      // 更新属性
      Array.from(newElement.attributes).forEach(attr => {
        this.element.setAttribute(attr.name, attr.value)
      })
      
      // 更新内容
      if (this.element.innerHTML !== newElement.innerHTML) {
        this.element.innerHTML = newElement.innerHTML
      }
    }
    
    this.bindEvents()
  }
  
  // 挂载组件
  mount(container) {
    this.beforeMount()
    
    this.element = this.render()
    this.bindEvents()
    
    if (container) {
      container.appendChild(this.element)
    }
    
    this.lifecycle.mounted = true
    this.mounted()
    
    return this.element
  }
  
  // 卸载组件
  unmount() {
    this.beforeDestroy()
    
    if (this.element && this.element.parentNode) {
      this.element.parentNode.removeChild(this.element)
    }
    
    this.unbindEvents()
    this.lifecycle.destroyed = true
    this.destroyed()
  }
  
  // 事件绑定
  bindEvents() {
    this.eventListeners.forEach((handler, selector) => {
      const elements = this.element.querySelectorAll(selector)
      elements.forEach(el => {
        const [event, callback] = handler
        el.addEventListener(event, callback)
      })
    })
  }
  
  // 事件解绑
  unbindEvents() {
    this.eventListeners.forEach((handler, selector) => {
      const elements = this.element.querySelectorAll(selector)
      elements.forEach(el => {
        const [event, callback] = handler
        el.removeEventListener(event, callback)
      })
    })
  }
  
  // 添加事件监听器
  addEventListener(selector, event, callback) {
    this.eventListeners.set(selector, [event, callback.bind(this)])
  }
  
  // 创建元素辅助方法
  createElement(tag, attributes = {}, children = []) {
    const element = document.createElement(tag)
    
    // 设置属性
    Object.entries(attributes).forEach(([key, value]) => {
      if (key === 'className') {
        element.className = value
      } else if (key === 'style' && typeof value === 'object') {
        Object.assign(element.style, value)
      } else {
        element.setAttribute(key, value)
      }
    })
    
    // 添加子元素
    children.forEach(child => {
      if (typeof child === 'string') {
        element.appendChild(document.createTextNode(child))
      } else if (child instanceof HTMLElement) {
        element.appendChild(child)
      } else if (child instanceof Component) {
        element.appendChild(child.mount())
      }
    })
    
    return element
  }
}

// 用户卡片组件
class UserCard extends Component {
  constructor(props) {
    super(props)
    
    this.addEventListener('.edit-btn', 'click', this.handleEdit)
    this.addEventListener('.delete-btn', 'click', this.handleDelete)
  }
  
  render() {
    const { user } = this.props
    
    return this.createElement('div', {
      className: 'user-card',
      'data-user-id': user.id
    }, [
      this.createElement('div', { className: 'user-avatar' }, [
        this.createElement('img', {
          src: user.avatar || '/default-avatar.png',
          alt: user.name
        })
      ]),
      this.createElement('div', { className: 'user-info' }, [
        this.createElement('h3', {}, [user.name]),
        this.createElement('p', {}, [user.email]),
        this.createElement('span', { className: 'user-role' }, [user.role])
      ]),
      this.createElement('div', { className: 'user-actions' }, [
        this.createElement('button', { className: 'edit-btn' }, ['Edit']),
        this.createElement('button', { className: 'delete-btn' }, ['Delete'])
      ])
    ])
  }
  
  handleEdit() {
    if (this.props.onEdit) {
      this.props.onEdit(this.props.user)
    }
  }
  
  handleDelete() {
    if (this.props.onDelete) {
      this.props.onDelete(this.props.user)
    }
  }
}

// 用户列表组件
class UserList extends Component {
  constructor(props) {
    super(props)
    
    this.state = {
      users: props.users || [],
      loading: false,
      error: null
    }
  }
  
  render() {
    const { users, loading, error } = this.state
    
    if (loading) {
      return this.createElement('div', { className: 'loading' }, ['Loading users...'])
    }
    
    if (error) {
      return this.createElement('div', { className: 'error' }, [`Error: ${error}`])
    }
    
    if (users.length === 0) {
      return this.createElement('div', { className: 'empty-state' }, ['No users found'])
    }
    
    const userCards = users.map(user => 
      new UserCard({
        user,
        onEdit: this.props.onEditUser,
        onDelete: this.props.onDeleteUser
      })
    )
    
    return this.createElement('div', { className: 'user-list' }, userCards)
  }
  
  updateUsers(users) {
    this.setState({ users })
  }
  
  setLoading(loading) {
    this.setState({ loading })
  }
  
  setError(error) {
    this.setState({ error })
  }
}

// 应用主组件
class App extends Component {
  constructor(props) {
    super(props)
    
    this.state = {
      users: [],
      currentView: 'list'
    }
    
    this.userList = new UserList({
      users: this.state.users,
      onEditUser: this.handleEditUser.bind(this),
      onDeleteUser: this.handleDeleteUser.bind(this)
    })
  }
  
  async mounted() {
    await this.loadUsers()
  }
  
  async loadUsers() {
    this.userList.setLoading(true)
    
    try {
      const response = await fetch('/api/users')
      const users = await response.json()
      
      this.setState({ users })
      this.userList.updateUsers(users)
    } catch (error) {
      this.userList.setError(error.message)
    } finally {
      this.userList.setLoading(false)
    }
  }
  
  handleEditUser(user) {
    console.log('Edit user:', user)
    // 实现编辑用户逻辑
  }
  
  handleDeleteUser(user) {
    if (confirm(`Are you sure you want to delete ${user.name}?`)) {
      const users = this.state.users.filter(u => u.id !== user.id)
      this.setState({ users })
      this.userList.updateUsers(users)
    }
  }
  
  render() {
    return this.createElement('div', { className: 'app' }, [
      this.createElement('header', { className: 'app-header' }, [
        this.createElement('h1', {}, ['User Management'])
      ]),
      this.createElement('main', { className: 'app-main' }, [
        this.userList
      ])
    ])
  }
}

// 启动应用
document.addEventListener('DOMContentLoaded', () => {
  const app = new App()
  const container = document.getElementById('app')
  app.mount(container)
})

状态管理架构

// 现代状态管理系统
class Store {
  constructor(initialState = {}, reducers = {}) {
    this.state = initialState
    this.reducers = reducers
    this.subscribers = []
    this.middleware = []
  }
  
  // 添加中间件
  use(middleware) {
    this.middleware.push(middleware)
  }
  
  // 获取状态
  getState() {
    return { ...this.state }
  }
  
  // 分发动作
  dispatch(action) {
    // 应用中间件
    let next = (action) => {
      const reducer = this.reducers[action.type]
      if (reducer) {
        const newState = reducer(this.state, action)
        this.setState(newState)
      }
    }
    
    // 从右到左应用中间件
    for (let i = this.middleware.length - 1; i >= 0; i--) {
      next = this.middleware[i](this)(next)
    }
    
    next(action)
  }
  
  // 设置状态
  setState(newState) {
    const prevState = this.state
    this.state = { ...this.state, ...newState }
    
    // 通知订阅者
    this.subscribers.forEach(subscriber => {
      subscriber(this.state, prevState)
    })
  }
  
  // 订阅状态变化
  subscribe(callback) {
    this.subscribers.push(callback)
    
    // 返回取消订阅函数
    return () => {
      const index = this.subscribers.indexOf(callback)
      if (index > -1) {
        this.subscribers.splice(index, 1)
      }
    }
  }
}

// 日志中间件
const loggerMiddleware = (store) => (next) => (action) => {
  console.group(`Action: ${action.type}`)
  console.log('Previous State:', store.getState())
  console.log('Action:', action)
  
  const result = next(action)
  
  console.log('Next State:', store.getState())
  console.groupEnd()
  
  return result
}

// 异步中间件
const thunkMiddleware = (store) => (next) => (action) => {
  if (typeof action === 'function') {
    return action(store.dispatch, store.getState)
  }
  
  return next(action)
}

// 用户状态管理
const userReducers = {
  'FETCH_USERS_START': (state, action) => ({
    ...state,
    users: {
      ...state.users,
      loading: true,
      error: null
    }
  }),
  
  'FETCH_USERS_SUCCESS': (state, action) => ({
    ...state,
    users: {
      ...state.users,
      loading: false,
      data: action.payload,
      error: null
    }
  }),
  
  'FETCH_USERS_ERROR': (state, action) => ({
    ...state,
    users: {
      ...state.users,
      loading: false,
      error: action.payload
    }
  }),
  
  'ADD_USER': (state, action) => ({
    ...state,
    users: {
      ...state.users,
      data: [...state.users.data, action.payload]
    }
  }),
  
  'UPDATE_USER': (state, action) => ({
    ...state,
    users: {
      ...state.users,
      data: state.users.data.map(user => 
        user.id === action.payload.id ? action.payload : user
      )
    }
  }),
  
  'DELETE_USER': (state, action) => ({
    ...state,
    users: {
      ...state.users,
      data: state.users.data.filter(user => user.id !== action.payload)
    }
  })
}

// 动作创建器
const userActions = {
  fetchUsers: () => async (dispatch, getState) => {
    dispatch({ type: 'FETCH_USERS_START' })
    
    try {
      const response = await fetch('/api/users')
      const users = await response.json()
      
      dispatch({
        type: 'FETCH_USERS_SUCCESS',
        payload: users
      })
    } catch (error) {
      dispatch({
        type: 'FETCH_USERS_ERROR',
        payload: error.message
      })
    }
  },
  
  addUser: (userData) => async (dispatch) => {
    try {
      const response = await fetch('/api/users', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(userData)
      })
      
      const newUser = await response.json()
      
      dispatch({
        type: 'ADD_USER',
        payload: newUser
      })
    } catch (error) {
      console.error('Failed to add user:', error)
    }
  },
  
  updateUser: (user) => ({
    type: 'UPDATE_USER',
    payload: user
  }),
  
  deleteUser: (userId) => ({
    type: 'DELETE_USER',
    payload: userId
  })
}

// 创建store
const initialState = {
  users: {
    data: [],
    loading: false,
    error: null
  }
}

const store = new Store(initialState, userReducers)

// 添加中间件
store.use(loggerMiddleware)
store.use(thunkMiddleware)

// 连接组件到store
class ConnectedComponent extends Component {
  constructor(props) {
    super(props)
    
    this.store = props.store
    this.unsubscribe = null
  }
  
  mounted() {
    // 订阅store变化
    this.unsubscribe = this.store.subscribe((state, prevState) => {
      this.onStateChange(state, prevState)
    })
  }
  
  destroyed() {
    // 取消订阅
    if (this.unsubscribe) {
      this.unsubscribe()
    }
  }
  
  onStateChange(state, prevState) {
    // 子类实现
  }
  
  dispatch(action) {
    this.store.dispatch(action)
  }
  
  getState() {
    return this.store.getState()
  }
}

// 使用连接的组件
class UserManagementApp extends ConnectedComponent {
  constructor(props) {
    super(props)
    
    this.state = {
      users: []
    }
  }
  
  mounted() {
    super.mounted()
    
    // 初始加载用户
    this.dispatch(userActions.fetchUsers())
  }
  
  onStateChange(state, prevState) {
    const users = state.users.data
    if (users !== prevState.users.data) {
      this.setState({ users })
    }
  }
  
  handleAddUser(userData) {
    this.dispatch(userActions.addUser(userData))
  }
  
  handleDeleteUser(userId) {
    this.dispatch(userActions.deleteUser(userId))
  }
  
  render() {
    const { users } = this.state
    const { loading, error } = this.getState().users
    
    return this.createElement('div', { className: 'user-management-app' }, [
      this.createElement('h1', {}, ['User Management']),
      loading && this.createElement('div', { className: 'loading' }, ['Loading...']),
      error && this.createElement('div', { className: 'error' }, [error]),
      this.createElement('div', { className: 'user-list' }, 
        users.map(user => 
          this.createElement('div', { 
            className: 'user-item',
            key: user.id 
          }, [
            this.createElement('span', {}, [user.name]),
            this.createElement('button', {
              onclick: () => this.handleDeleteUser(user.id)
            }, ['Delete'])
          ])
        )
      )
    ])
  }
}

// 启动应用
const app = new UserManagementApp({ store })
app.mount(document.getElementById('app'))

总结

前端架构模式的核心要点:

  1. MVC模式:分离关注点,模型-视图-控制器职责清晰
  2. MVVM模式:双向数据绑定,视图模型作为桥梁
  3. 组件化架构:可复用组件,生命周期管理
  4. 状态管理:集中式状态,可预测的状态变化
  5. 现代实践:结合函数式编程、响应式编程理念

架构模式的选择应该基于项目规模、团队技能和业务需求。现代前端开发趋向于组件化、模块化和函数式编程,注重可维护性和可测试性。