Concept:

Generic programming is a style or paradigm of programming languages. Generics allow programmers to write code in strongly typed programming languages using types that are specified later and specified as parameters when instantiated.

Generic applications:

Scene: in the front and back end interactive data interface unified return format definition of the scene to carry out generic actual combat training.

  1. Query the format of the packet returned by the specified data by ID:

  1. The format of the packet returned by querying the entire list is as follows:

Some information can be obtained by analyzing the two returned packets:

  1. Public and determine class attributescodeandmessage;
  2. A common but indeterminate property result, which can be an object or an array;
  3. The list object must contain the common attributes size and Pages when the packet of list data is returned.
  4. Both the single element in the return list data and the object that returns the specified data contain a common ID field that can be extracted and used in the common parent class, because the database must have a unique identity for the data;

Take a look at the structure without generics through a UML class diagram

BaseResponse:

Extract interface common attributes: code, message, result

class BaseResponse {
  code: number;
  message: string;
  result: any;

  constructor(code = 200, message: string, result: any) {
    this.code = code;
    this.message = message;
    this.result = result; }}Copy the code
BaseData:

A unique primary key ID for impersonating database table data

class BaseData {
  id: number;
  constructor(id: number) {
    this.id = id; }}Copy the code
Person:

Simulate database staff form bar data

class Person extends BaseData {
  name: string;
  age: number;
  constructor(id: number, name: string, age: number) {
    super(id);
    this.name = name;
    this.age = age; }}Copy the code
ListPersonData:

Simulated database personnel table multiple data

class ListPersonData {
  size: number;
  pages: number;
  persons: Person[];
  constructor(size: number, pages: number, persons: Person[]) {
    this.size = size;
    this.pages = pages;
    this.persons = persons; }}Copy the code
ListPersonResponse:
class ListPresonResponse extends BaseResponse {
  // Assemble data
  static toResponse(): object {
    const person = new Person(100."zhangsan".18);
    const result = new ListPersonData(20.1, [person]);
    const listDataResponse = new ListPresonResponse(
      200."Data loading completed",
      result
    );
    returnlistDataResponse; }}Copy the code
PersonResponse:
class PersonResponse extends BaseResponse {
  // Assemble data
  static toResponse(): object {
    const person = new Person(100."zhangsan".18);
    const personResponse = new PersonResponse(200."Data loading completed", person);
    returnpersonResponse; }}Copy the code

No generic structure description:

From the output, we can see that the requirements have been implemented, and we can also see that the direct relationship between the classes is relatively close, which is not conducive to extension and maintenance. Let’s see what happens when we apply generics.

To upgrade a class – apply generics:

1. Support generics for BaseResponse:
class BaseResponse<T> {
  code: number;
  message: string;
  result: T;

  constructor(code = 200, message: string, result: T) {
    this.code = code;
    this.message = message;
    this.result = result; }}Copy the code
2. Configure the generic type for the ListPresonResponse error:
class ListPresonResponse extends BaseResponse<ListPersonData> {
  // Assemble data
  static toResponse(): object {
    const person = new Person(100."zhangsan".18);
    const result = new ListPersonData(20.1, [person]);
    const listDataResponse = new ListPresonResponse(
      200."Data loading completed",
      result
    );
    returnlistDataResponse; }}Copy the code
  1. Type prompt before configuring generic types :(can only be any because the type is uncertain)

  1. Type prompt after configuring generic types:

3. Configure the generic type for the offending PersonResponse:
class PersonResponse extends BaseResponse<Person> {
  // Assemble data
  static toResponse(): object {
    const person = new Person(100."zhangsan".18);
    const personResponse = new PersonResponse(200."Data loading completed", person);
    returnpersonResponse; }}Copy the code
  1. Type warning before configuring a generic type :(can only be any because the type is uncertain)

  1. Type prompt after configuring generic types:

4. The ListPersonData class that returns the list of data we apply generics to transform and extract into a unified ListData class

Remember that ListData is a public class that does not display associations with other classes

class ListData<T extends BaseData> {
  size: number;
  pages: number;
  list: T[];
  constructor(size: number, pages: number, list: T[]) {
    this.size = size;
    this.pages = pages;
    this.list = list; }}Copy the code
5. Adjust ListPresonResponse to meet our generic rules
class ListPresonResponse extends BaseResponse<ListData<Person>> {
  // Assemble data
  static toResponse(): object {
    const person = new Person(100."zhangsan".18);
    const result = new ListData(20.1, [person]);
    const listDataResponse = new ListPresonResponse(
      200."Data loading completed",
      result
    );
    returnlistDataResponse; }}Copy the code

After applying generics:

After applying generics, the code becomes easier to expand. If we add a new commodity table, the corresponding structure of single data return and multiple data return can be easily extended in the original base class. If the attribute extension and change need to be carried out in the base class, all the subclasses will be affected. Let’s look at the added class for commodity object messages:

class Goods extends BaseData {
	// Implement internal attributes
}
class ListGoodsResponse extends BaseResponse<ListData<Goods>> {
	// Implement the assembly data function.
}
class GoodsResponse extends BaseResponse<Goods> {
	// Implement the assembly data function.
}
Copy the code

Conclusion:

The application of generics enables us to abstract the structure of the program in the design process without specifying the type of the concrete class, so that the base class becomes a regular loose, delayed until the implementation of the subclass to supplement the generic type for clarification.