MVC (Model-View-Controller pattern)

Model-view-controller is one of the frequently used software architecture patterns in software development. It divides the software system into three basic layers: Model, View and Controller.

  • Model layer: includes the application’s data, interaction with the database, and business logic to process the data;
  • View layer: render business data into visual pages;
  • Control layer: the link between the user and the system. It manages and processes the user’s input in the view layer (including form submission, mouse click, etc.) and instructs the model layer and the view layer to perform relevant operations based on the user’s input.

MVC architecture mode makes the system code stratified clearly, with low coupling of code, easy to develop quickly and other advantages.

MVC example, the pseudocode is as follows:

/ / the data layer
const model = {
  data: { // Data initialization
    n: parseInt(localStorage.getItem('number') | |100)},update: function (data) { /* Update data */ },
  delete: function (data) { /* Delete data */ },
  get: function (data) { /* Get data */}}/ / the view layer
const view = { 
  el: 'Mount point (container)'.templete: 'NEED to insert HTML content inside element'.render(data){ /* Render the HTML view after retrieving the data */}}/ / control layer
const controller = { 
  // Get the DOM element and bind the event
  // If the event is triggered to call the change data method and render method
  a: $('#a'),
  b: $('#b'),
  c: $('#c'),
  bindEvents: function(){   // bindEvents executes at render
    a.on('click'.function(){
      // Call the data layer method to change the data
      // Call the view-layer method to render the page
    })
    b.on('click'.function(){Above / * * /})
    c.on('click'.function(){Above / * * /}}})Copy the code

EventBus (EventBus mode)

Event bus pattern is also one of the frequently used software architecture patterns in software development. Event Bus pattern is applied to event processing and mainly consists of four components:

  • Event Source
  • Event Listener
  • Channel
  • Event Bus

Event sources publish messages to specific channels of the bus, listeners subscribe to the corresponding channels, and messages published by the event source are advertised to listeners of the subscribed channels.

The event bus pattern is an implementation of the publish/subscribe pattern. It is a centralized event processing mechanism that allows different components to communicate with each other but not depend on each other, achieving loose coupling.

EventBus has three common apis: on(), trigger(), and off().

  • On () is used to listen for events
  • Trigger () is used to trigger events
  • Off () is used to cancel listening

For the EventBus example, the pseudocode is as follows:

import $ from 'jquery'
const eventbus = $(window) // Return an object containing all the methods of eventBus

/ / the data layer
const model = { 
  data: {'data':1},
  update(data){
    Object.assign(model.data,data) // Take all arguments and put them into the object
    eventbus.trigger('Update data') // Trigger the event}}/ / the view layer
const view = {
  el: 'Mount point'.html: Content: '< div > {{}} < / div >'.init(container){
    view.el = $(container)
  },
  render(data){
    $(view.html.replace('{{n}}', n)).appendTo(view.el) // Replace the new (data) content, render into the page}}const controller = {
  init(container){
    view.init(container)  // Get the mount point (element container)
    view.render(m.data.n) // Initialize the page
    autoBindEvents()
    eventbus.on('Update data'.() = > { 
      // Listen for eventbus.trigger in the data layer
      // If it is triggered, the data is updated for rendering
      view.render(m.data.n)
    })
  },
  add() { // Change the data
    m.update({n: m.data.n + 1})},minus() { // Change the data
    m.update({n: m.data.n - 1})},autoBindEvents() {  // Listen for buttons to change data
    view.el.on('click'.'app1'.'add')}}Copy the code

Table driven programming

Table-Driven Methods (Table-Driven Methods) is a programming mode.

Advantages: Eliminate frequent if-else or switch-case logical structure code in code, simplifying code.

Example 1 (Array)

Enter the year and month to return the corresponding days. Leap year meet :(four years a embellish and one hundred years not embellish) or (four hundred years embellish)

Conventional writing:

function getDay(year, month) {
  let isLeapYear = year % 4= = =0 && year % 100! = =0 || year % 400= = =0 ? 1 : 0
  if (month === 2) {
    return 28 + isLeapYear
  } else if (month===1||month===3||month===5||month===7||month===8||month===10||month===12) {
    return 31
  } else if (month === 4 || month === 6 || month === 9 || month === 11) {
    return 30}}console.log(getDay(2020.6))  / / 30
console.log(getDay(2020.2))  / / 29
console.log(getDay(2019.2))  / / 28
Copy the code

Table driven writing:

const monthDays = [
  [31.28.31.30.31.30.31.31.30.31.30.31],
  [31.29.31.30.31.30.31.31.30.31.30.31]]function getDay(year, month){
  let isLeapYear = year % 4= = =0 && year % 100! = =0 || year % 400= = =0 ? 1 : 0
  return monthDays[isLeapYear][month-1]}console.log(getDay(2020.6))  / / 30
console.log(getDay(2020.2))  / / 29
console.log(getDay(2019.2))  / / 28
Copy the code

Example 2 (object)

Listen for multiple element binding events

Conventional writing:

add1(){}min1(){}mul2(){}div2(){}document.querySelector('#add1').addEventListener('click', add1)
document.querySelector('#min1').addEventListener('click', min1)
document.querySelector('#mul2').addEventListener('click', mul2)
document.querySelector('#div2').addEventListener('click', div2)
Copy the code

Table driven writing:

const controller = {
  add1(){},min1(){},mul2(){},div2(){},events: { // Table driver programming (object)
    "click #add1": "add1".// The first half of the key is the event to listen on, the second half is the element to listen on, and the value is the method to execute
    "click #min1": "min1"."click #mul2": "mul2"."click #div2": "div2"
  },
  autoBindEvents() {
    for(let key in this.events){ // Iterate over the object to get the corresponding key to perform the assignment
      const handler = this[this.events[key]]
      const [event, selector] = key.split("")  // ["click", "#min1"] ES6 syntax: destruct assignment
      $("Container").on(event, selector, handler) // Listen for events with extracted values}}}Copy the code

The “regular” code is simpler and straightforward, but it’s too repetitive. As the size of the data gets bigger, if you’re listening for 10 or 100 events, then the amount of code that’s written in this way also increases and table-driven programming allows the code to have a steady level of complexity, keeping it simple regardless of the size of the data.

Modular programming

The overall function of the system is separated into each independent function, which reduces the coupling degree of code, reduces the repeated code, improves the code reuse, and makes the project structure clearer and easier to maintain.

JavaScript modular process reference JavaScript modular programming, Huang Xuan’s modular seven days talk

reference

  • Analysis of MVC Architecture
  • MVC is analysed
  • Modular programming of JavaScript
  • A brief introduction to 10 common software architectures