preface

Alas, there are a lot of fish recently, resulting in a delay of 0.5d requirements, before the next fish, must first split requirements, and see your teammates (front and rear end) design and implementation. Otherwise the time is all pit, buried is their own.

Next time, I want to touch the beginning of fish, which is more suitable for me, hahaha hahaha. Get down to business!!

Business background

Recently done this requirement, similar to the picture, video (material) background management module, very simple to implement, filter list and data display list. But… The e problem is not the business logic of the page, but the backend interface design. Collectively referred to below as pages representing images and videos

FBI Warning!

This requirement is the one I came up with through my whimsical idea of realizing the image preview with frosted glass. Coincidence? One need, got two knowledge points and shared with everyone ~ ~

So next, ahem, I continue to use the previous drawing for you, the need prototype is similar to the following!!

For example, there are currently material upload, download, screening items, lists, export, download, etc.

There are 12 interfaces corresponding to the back end

  • Image upload
  • Images are downloaded
  • Image filters
  • List of pictures
  • Image export
  • Image download
  • Upload video
  • Video download
  • Filter the video
  • List of videos
  • Video export
  • Video download

Above… However, the UI of the front-end page is almost identical. It only needs to distinguish the copywriting of video and picture and the prefix of the corresponding module when requesting the corresponding interface, such as image and video, etc

Before the implementation

Since this requirement is a similar module in a previous system, the back-end is directly used, and the UI at the front is changed. Besides, the code written before is bloated and the technology stack is backward (first, I have modules before I come to the company). It’s hard to maintain, and for those two reasons, I definitely need to rewrite it.

But when I saw the interface documentation from the back end, I said no. I hope the backend can unify the interface, the front-end exposed fields and the interface is the most simple (otherwise, you give me the database, I directly add, delete, change and check the database is not also ok?) “, but the back end big Brother gave me refused to refuse. It has already been implemented (the previous system code was taken to use) and cannot be changed.

Design the front intermediate layer

Since the backend big brother won’t change, we should exercise our own ability, don’t you think? Then neng!

Some time ago, I also read “JavaScript Design Patterns and Development Practices” by Zeng Da Lao, and benefited a lot. Recommend!!

First of all, common components that are similar to other modules are removed for reuse and flexibility of components, which I won’t go into here. A SearchBar component and a CardList component can be called by each page-level component, passing in the corresponding options. Mainly to design how to achieve a set of UI two sets of interfaces of the middle layer components

No more nonsense, directly on the code and the corresponding train of thought

Train of thought

  1. It is good to distinguish video and picture according to different types of page, which has good expansibility. For example, after adding audio, it is just adding a type. Enumerations are used to enumerate types. For example, if you need to change the enumeration, you only need to change one place and the whole system will change
  2. The mediator pattern is needed to control the presentation of two different modules and the corresponding encapsulation
  3. The prototype technology is used to realize the responsibility chain pattern and encapsulate the interface dynamically
  4. Dynamic concatenation (overwriting) of parameters to achieve the different field parameter passing at the back end

implementation

  1. It’s easier to separate pages according to the type you are usingPropsOr the URLqueryWill do. Currently I am through componentsPropsTo pass the
export default function ImageManagement() {
  return <MaterialManagement type={MATERIAL_TYPE.IMAGE} />
}

Copy the code
  1. Use the mediator pattern to encapsulate uniform behavior

The mediator pattern: The role of the mediator pattern is to decouple objects from each other. “JavaScript Design Patterns and Practices” — Zeng

function MediatorPattern(this: any, type: number) :any {
  this.type = type
  For example, if you add other types later, you can change them to enumeration form to add them
  // There is only one image and one video
  this.isImage = this.type === MATERIAL_TYPE.IMAGE
  this.prefix = this.isImage ? 'image' : 'video'
  this.text = this.isImage ? 'images' : 'video'
  this.method = this.isImage ? imageAPI : videoAPI
  
  
  // Business use must begin with an uppercase as a field to be considered an argument to be overridden
  // In the last step, dynamic concatenation parameters need to be used
  this.dynamicParams = [
  	// ...
    'Size'.// ...]}Copy the code

Our UI component here doesn’t really care if it’s an image or video or audio or whatever, we just have to deal with the specific logic. For example, if several types are added later, we can maintain the mediator object without any logic at the UI level. Disconnect the coupling between all types.

  1. The prototype technology is used to realize the responsibility chain pattern and encapsulate the interface dynamically

For example, NOW I need a list interface, and the method I need has been inserted into this.method through the intermediary mode. At this time, we can call the corresponding interface according to the method here, but we do not know whether the current interface is picture or video, so we need the responsibility chain mode for processing

Chain of responsibility pattern: Avoid coupling between senders and receivers of requests by giving multiple objects the opportunity to process requests, link these objects into a chain, and pass the request along the chain until one object processes it. “JavaScript Design Patterns and Practices” — Zeng

// Get a list of pictures/videos
MediatorPattern.prototype.getList = function (params: any) {
  const newParams = this.rewriteParams(params)
  // Chain of responsibility mode, process the request, if the current chain cannot process, then continue processing
  // There is no bottom-feeding strategy here, you can add according to your own needs
  return (
    this.method.getImageList? .(newParams) ??this.method.getVideoList? .(newParams) ) }Copy the code

? And?? All ES6+ grammar, the first time to see the students can check oh

So we just need to call

const params = {
	pageNum: 1.pageSize: 10
}
const response = await MediatorPattern.getList(params)
/ /... Other logic
Copy the code

So interfaces like upload, download, import, etc., can be written in this way, so the UI component level only needs to care about what interface you are fetching data from.

  1. Dynamic concatenation (overwriting) of parameters to achieve the different field parameter passing at the back end

Since we have encapsulated all types, functions, and interfaces, we also need to encapsulate the parameters at the parameter level.

For example, the size fields returned to the front end are imageSize and videoSize, so the front end also needs the corresponding concatenation, which is easier. Concatenate code directly

// Parameter dynamic encapsulation, mainly used to distinguish images and video similar parameters, for example
// {imageSize: ''}, {videoSize: ''} => {Size: ''
MediatorPattern.prototype.rewriteParams = function (params: any) {
  const newParams: any = {}
  for (const key in params) {
    if (this.dynamicParams.includes(key)) {
      newParams[`The ${this.prefix}${key}`] = params[key]
      continue
    }
    newParams[key] = params[key]
  }

  return newParams
}
Copy the code

We make distinctions based on variable names, which requires that our naming be in good programming style

conclusion

Well, all of our functionality and packaging is now complete.

Through this demand development, also want to let everyone feel, do not bury your head in the current work, every dull demand is worth your careful thinking! If I just kept my head down on the requirement, I would have written a page, copied the components, and then changed the copy and API. Isn’t it? To sum up: Don’t repeat yourself.

Well, if the above where write wrong, big guy excuse me, tell me, timely correction!

Finally, I would like to recommend “JavaScript design pattern and development practice”, which is very good.

Writing is not easy!! Last time I wrote a fishy article, this demand has been delayed by 0.5 days. This article was written by me as soon as I got home from work. The requirements were tested last week. I had time to write this article. If there’s one or more of these things that you get. Just give it a thumbs up! Did not get, if you read carefully, you know that I write is not easy, also give a praise ~ ~