Wheel building project

Plans change every day

  • The framework
    • A template engine
    • Anti-shake and throttling
    • Response principle
    • Unified State Management
    • Time travel
    • Mixin
    • Native Ajax
  • JS based
    • Compose
    • Promise
    • Promise.all/race
    • routing
    • new
    • [call/apply/bind](./call apply bind)
    • Object.create
    • Deep copy, shallow copy
  • Algorithms, design patterns
    • Binary search
    • Fast row
    • Binary search
    • Bubble sort
    • Selection sort
    • Subscribe to the published
    • Fibonacci algorithm
    • duplicate removal

What is middleware

Middleware can be interpreted two different ways.

1. Traditional middleware concepts

wikipedia

Middleware (English: Middleware) is the software that provides the connection between system software and application software, so as to facilitate the communication between software components, especially the centralized logic of application software to system software. It is widely used in modern information technology application frameworks such as Web services and service-oriented architecture. For example, database, Tomcat of Apache, WebSphere of IBM, WebLogic application server of BEA, Tong series middleware of Dongfang Tong and Kingdee company all belong to middleware.

Once upon a time,

In May 1988, the ordinary technicians of Qiubojun wrote WPS (Word Processing System) 1.0 in a rented room of a hotel with a 386 computer, which ushered in the Era of Chinese Word Processing.

Writing programs in those days was basically written in C directly on the operating system

Operating system => Service programs

But then you find that a complex business application can often split into two layers, you can pull out a layer of application that is completely irrelevant to the business like Web services, data storage, etc.

Operating system => Middleware => business applications

This is the original concept of middleware.

Middleware can mask the underlying operating system and reduce the complexity of programming.

Operating system (Linux) => Middleware => business program

Operating system (Windows) => Middleware => business program

Operating system (Unix SCO) => Middleware => business program

Common middleware products

  • Application servers: JBoss, Tomcat, Geronimo, JOnAS
  • Message middleware: Kafka, RabbitMQ
  • Trading middleware: TUXEDO, TUXONE

2. Middleware in the JS world

The JS world has middleware implementations in Express, Koa, and Redux. In fact, this middleware is mainly for the convenience of assembling business logic into a logic processing chain. In fact, it is a realization of the responsibility chain pattern in the design pattern. We also refer to him as the Onion ring model.

3. It’s designed for faceted programming

For complex systems, aspect programming is a must. Before and after completing a core logic, or coarse errors need to be handled accordingly.

Like transferring money:

  • Before transfer: Authentication security opens transaction

  • After transfer: Operation log closes transaction

  • Exception: Account rollback error log

Imagine how much trouble it would be if we had hard coding.

transfer() {
  / / authentication
  tokenCheck()

  // Start the transaction
  tx.begin()
  try {

    // Core logic

    // Operation log
    log(' xxxxxx ')}cache(err) {
    // Error log
    log(' xxxxxx ')
    // Rollback the transaction
    tx.rollback
  } finally {
    // Close the transaction
    tx.end
  }
}

Copy the code

That’s not all, if you want to add synchronization locks, resource pool fetching (such as database connection pooling), and caching.

The solution is to provide the possibility of AOP programming.

The name “aspect oriented programming” is not very easy to understand and can be misleading. Some people think “OOP/OOD11 is going out the window and AOP is the next generation of software development”. Clearly, the speaker did not understand what AOP meant. A: What do you mean by that? However, the “aspect” in traditional Chinese semantics mostly refers to the different dimensions or characteristics of a thing from different angles. For example, we often say “this thing should be looked at from several aspects”, which usually means that the same thing needs to be looked at from different angles. The “aspect” here refers to the manifestation of the external characteristics of things in different observation angles. In AOP, Aspect may be better understood as “Aspect”.

If there is aspect programming, the code usually just needs to be done at once before defining what to do with all the business, right

@Before(tokenCheck) / / authentication
@Before(tx.begin) // Start the transaction
@After(log) // Operation log
@After(tx.end) // Close the transaction
@Exception(log) // Error log
@Exception(tx.rollback) // Rollback the transaction
traansferBase() {
  // Business logic
}
Copy the code

Of course I wrote this in the form of Anotation, but you just need to define it once and you can execute it all.

Full with high cohesion and low coupling.

4. Creation of onion rings

In fact, there are many ways to achieve the purpose of AOP, and the onion ring is one of them.

It’s the chain of responsibility model, and the chain of responsibility model is like adding layers of onion rings to the core task.

It’s a chain of pre-processing, post-processing, and business procedures.

This can achieve the purpose of aspect programming.

Second, the demand for

Onion ring implementation needs to consider synchronous and asynchronous cases. This section only uses synchronization as an example.

For details please refer to the code: github.com/su37josephx…

it('Synchronization function'.async() = > {const mockFn = jest.fn()
        // const mockFn = console.log
        const middlewares = [
            next= > {
                mockFn('1 start')
                next()
                mockFn('1 end')},next= > {
                mockFn('2 start')
                next()
                mockFn('2 end')}]const func = compose(middlewares)

        viewLog && console.log('Sync function > compose definition', compose.toString());

        func();
        const calls = mockFn.mock.calls
        viewLog && console.log('First time', calls);
        expect(calls.length).toBe(4);
        expect(calls[0] [0]).toBe('1 start');
        expect(calls[1] [0]).toBe('2 start');
        expect(calls[2] [0]).toBe('2 end');
        expect(calls[3] [0]).toBe('1 end');

    })
Copy the code

Three, function realization

I mean, you could write about a dozen onion rings. The following codes are all homework for my students.

No1:Express recursive implementation

No2:Koa recursive implementation

No3:Koa Reduce implementations

No4:Koa Class implementation

No5:Redux Reduce implementations

No6:Redux ReduceRight implementation

No7:Redux ReduceRight Promise implementation

No8:Implementation of Chain of Responsibility Pattern

No9:[List via List recursion](

We’ll just name a few, but there’s a lot more. Welcome PR. I’ll talk about some more later.

1. Express recursive implementation

module.exports.compose = (middlewares = []) = > {
    if (!Array.isArray(middlewares)) {
        middlewares = Array.from(arguments);
    }

    if (middlewares.some(fn= > typeoffn ! = ='function')) {
        throw new TypeError('Middleware must be composed of functions! ');
    }

    return async() = > {let idx = 0;
        async function next() {
            if (idx === middlewares.length) {
                return Promise.resolve();
            }
            if (idx < middlewares.length) {
                return Promise.resolve(middlewares[idx++](next)); }}return await next();
    };
};

Copy the code

2.Koa recursive implementation

module.exports.compose = (middlewares = []) = > {
    if (!Array.isArray(middlewares)) {
        middlewares = Array.from(arguments);
    }

    if (middlewares.some(fn= > typeoffn ! = ='function')) {
        throw new TypeError('Middleware must be composed of functions! ');
    }

    return function () {
        return dispatch(0);
        function dispatch(i) {
            let fn = middlewares[i];
            if(! fn) {return Promise.resolve();
            }
            return Promise.resolve(
                fn(function next() {
                    return dispatch(i + 1); })); }}; };Copy the code

3. Reduce implementations

module.exports.compose = (middlewares = []) = > {
    if (!Array.isArray(middlewares)) {
        middlewares = Array.from(arguments);
    }

    if (middlewares.length === 0) {
        return arg= > arg;
    }

    if (middlewares.some(fn= > typeoffn ! = ='function')) {
        throw new TypeError('Middleware must be composed of functions! ');
    }

    return (next = async() = > {}) = > middlewares.reduce((a, b) = > arg= > a(() = > b(arg)))(next);
};

Copy the code

Fourth, sublimation expansion

It’s really the realization of the chain of responsibility, and I welcome you to finish the PR and make sure that you enter another world of transformation

Blog.csdn.net/liuwenzhe20…

Please refer to this great article

  • OOP style

Summary of

  • Object Oriented style OOP
    • Solution one uses template method pattern to realize responsibility chain pattern
    • The second solution uses the strategy pattern to realize the responsibility chain pattern
  • Functional Programming
    • Solution three uses first-class citizen function to replace strategy mode to realize responsibility chain mode
    • Solution four uses partial application function to realize responsibility chain pattern
    • Solution five uses partial function to realize responsibility chain pattern
  • Reactive Programming
    • Solution 6 Uses Actor model to realize responsibility chain pattern
    • Solution 7: RXReactive eXtension is used to realize the responsibility chain mode

Welcome to contribute PR

  • ★ ★ ★ ★ source address ★ ★ ★ ★ ★