- vừa được xem lúc

Blog#57: Design Patterns: Template Method Pattern trong TypeScript 😊 (Series: Bón hành TypeScript - PHẦN 7)

0 0 14

Người đăng: NGUYỄN ANH TUẤN

Theo Viblo Asia

Mình là TUẤN hiện đang là một Full-stack Web Developer tại Tokyo 😊. Nếu bạn thấy Blog này hay xin hãy cho mình một like và đăng ký để ủng hộ mình nhé 😉.

Chào mừng bạn đến với loạt bài Design Patterns trong TypeScript, tại đây mình giới thiệu một số Design Patterns hữu ích trong phát triển web bằng TypeScript.

Các Design Patterns rất quan trọng đối với các web developer và chúng ta có thể code tốt hơn bằng cách thành thạo chúng. Trong bài viết này, mình sẽ sử dụng TypeScript để giới thiệu Template Method Pattern.

Kịch bản thưởng gặp

CSV (Comma-Separated Values - Các value được phân tách bằng dấu phẩy) là định dạng tệp tương đối đơn giản. Tệp CSV lưu trữ dữ liệu dạng bảng (numbers and text) ở dạng văn bản thuần túy. Khi bạn cần xử lý dữ liệu CSV, quy trình xử lý tương ứng được hiển thị trong hình sau:

Sau khi hiểu được quy trình xử lý trên, chúng ta hãy sử dụng Node.js để implement function Parsing tệp csv.

users.csv

id,Name
1,Bytefer
2,Kakuqo

parse-csv.ts

import fs from "fs";
import path from "path";
import * as url from "url";
import { csvParse } from "d3-dsv";
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
const processData = (fileData: any[]) => console.dir(fileData);
const content = fs.readFileSync(path.join(__dirname, "users.csv"), "utf8");
const fileData = csvParse(content);
processData(fileData);

Trong đoạn code trên, chúng ta import mô-đun d3-dsv để implement function Parsing csv. Sau đó, chúng ta sử dụng esno để thực thi tệp parse-cvs.ts :

$ npx esno parse-csv.ts

Khi đoạn code trên chạy thành công, terminal sẽ xuất ra kết quả như sau:

[ { id: '1', Name: 'Bytefer' }, { id: '2', Name: 'Kakuqo' }, columns: [ 'id', 'Name' ]
]

Tiếp theo, Markdown là một ngôn ngữ đánh dấu văn bản nhẹ cho phép mọi người viết tài liệu ở định dạng văn bản thuần túy, dễ đọc và dễ viết. Để hiển thị tài liệu Markdown trên các trang web, chúng ta phải chuyển đổi tài liệu Markdown thành tài liệu HTML.

Để thực hiện được function trên, quy trình xử lý của chúng ta như sau:

Sau khi hiểu được quy trình xử lý trên, chúng ta hãy sử dụng Node.js để implement function Parsing Markdown.

Users.md

### Users
- Bytefer
- Kakuqo

parse-md.ts

import fs from "fs";
import path from "path";
import * as url from "url";
import { marked } from 'marked';
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
const processData = (fileData: any[]) => console.dir(fileData);
const content = fs.readFileSync(path.join(__dirname, "Users.md"), "utf8");
const fileData = marked.parse(content);
processData(fileData);

Trong đoạn code trên, chúng ta import mô-đun marked để thực hiện function Parsing Markdown. Sau đó, chúng ta lại sử dụng esno để thực thi tệp parse-md.ts :

$ npx esno parse-md.ts

Khi đoạn code trên chạy thành công, terminal sẽ xuất ra kết quả như sau:

'<h3 id="users">Users</h3>\n<ul>\n<li>Bytefer</li>\n<li>Kakuqo</li>\n</ul>\n'

Đối với hai ví dụ trước, mặc dù các loại tệp khác nhau được Parsing, nhưng bạn sẽ thấy rằng quá trình Parsing của chúng là tương tự nhau.

Toàn bộ quá trình chủ yếu bao gồm ba bước: đọc, Parsing và xử lý dữ liệu. Đối với kịch bản này, chúng ta có thể apply Template Method Pattern để gói gọn trình tự xử lý của ba bước trên.

Template Method Pattern

Template Method Pattern bao gồm hai phần: một abstract parent class và một implementation subclass cụ thể. Thông thường, khung thuật toán của subclass được đóng gói trong abstract parent class và nó cũng bao gồm việc thực hiện một số hàm public và thứ tự thực hiện của tất cả các hàm trong subclass được đóng gói. Bằng cách kế thừa abstract class này, các subclass cũng kế thừa toàn bộ cấu trúc thuật toán và có thể chọn ghi đè các hàm của parent class.

Tiếp theo, hãy xem cách implement trình Parsing CSV và Parsing Markdown bằng cách sử dụng Template Method Pattern.

Để hiểu rõ hơn về đoạn code sau, trước tiên chúng ta hãy xem sơ đồ lớp UML tương ứng:

Trong hình trên, chúng ta định nghĩa một abstract class FileParser và sau đó định nghĩa hai subclass, CsvParserMarkdownParser, tương ứng.

FileParser class

abstract class FileParser { // Template Method parse(filePath: string) { let content = this.readFile(filePath); let fileData = this.parseFile(content); this.processData(fileData); } readFile(filePath: string) { if (fs.existsSync(filePath)) { return fs.readFileSync(filePath, "utf8"); } } abstract parseFile(fileContent: string): any; processData(fileData: any[]) { console.log(fileData); }
}

Phương thức parse trong abstract class FileParser được gọi là Template method, trong đó chúng ta đóng gói quá trình xử lý tệp.

CsvParser class

class CsvParser extends FileParser { parseFile(fileContent: string) { return csvParse(fileContent); } }

MarkdownParser class

class MarkdownParser extends FileParser { parseFile(fileContent: string) { return marked.parse(fileContent); } }

Với hai lớp CsvParserMarkdownParser, chúng ta có thể Parsing CSV và Markdown theo các cách sau:

const csvParser = new CsvParser();
csvParser.parse(path.join(__dirname, "Users.csv")); const mdParser = new MarkdownParser();
mdParser.parse(path.join(__dirname, "Users.md"));

Khi bạn chạy thành công đoạn code trên, output tương ứng được hiển thị trong hình sau:

Bằng cách sử dụng Template Method Pattern, chúng ta đã implement lại việc Parsing CSV và Markdown. Trên thực tế, với abstract class FileParser, chúng ta có thể dễ dàng phát triển các chức năng Parsing cú pháp tệp khác nhau mà ko cần sửa Abstract class.

Các tình huống sử dụng của Template Method Pattern:

  • Các bước tổng thể của thuật toán là rất cố định, nhưng khi các phần riêng lẻ có thể thay đổi, Template Method Pattern có thể được sử dụng tại thời điểm này để trừu tượng hóa các phần dễ thay đổi cho các subclass thực hiện.

Các vấn đề tương tư như trên cũng hoàn toàn giải quyết được bằng Dependency Injection Pattern. Tương lai mình cũng sẽ có bài viết về chủ đề này các bạn nhớ đón xem nhé.

Roundup

Như mọi khi, mình hy vọng bạn thích bài viết này và học thêm được điều gì đó mới.

Cảm ơn và hẹn gặp lại các bạn trong những bài viết tiếp theo! 😍

Nếu bạn thấy Blog này hay xin hãy cho mình một like và đăng ký để ủng hộ mình nhé. Thank you.😉

Ref

Bình luận

Bài viết tương tự

- vừa được xem lúc

Giới thiệu Typescript - Sự khác nhau giữa Typescript và Javascript

Typescript là gì. TypeScript là một ngôn ngữ giúp cung cấp quy mô lớn hơn so với JavaScript.

0 0 500

- vừa được xem lúc

Type annotation vs Type Inference - Typescript

Trong bài viết này, chúng ta sẽ tìm hiểu kỹ về TypeScript bằng cách tìm hiểu sự khác biệt giữa kiểu chú thích và kiểu suy luận. Tôi sẽ cho rằng bạn có một số kinh nghiệm về JavaScript và biết về các kiểu cơ bản, như chuỗi, số và boolean.

0 0 32

- vừa được xem lúc

Type Annotation và Type Inference trong TypeScript là gì?

Khi làm việc với javascript chắc hẳn các bạn đã quá quen với việc dùng biến mà không cần phải quan tâm đến kiểu dữ liệu của nó là gì phải không? Đúng là mới đầu tiếp cận với Typescript mình cũng cảm thấy nó khá là phiền vì cần phải khai báo đủ type để nó chặt chẽ hơn. Lúc đó mình còn nghĩ: " JavaScr

0 0 25

- vừa được xem lúc

Tìm hiểu TypeScript và kiến thức cơ bản

TypeScript là gì. TypeScript sử dụng tất cả các tính năng của của ECMAScript 2015 (ES6) như classes, modules.

0 0 35

- vừa được xem lúc

TypeScript - P1: Vì sao TypeScript được yêu thích đến vậy?

Trải nghiệm thực tế. Trước khi là một Web Developer, tôi là một Mobile Developer và Java là thứ mà tôi từng theo đuổi.

0 1 58

- vừa được xem lúc

4 Tính năng rất hay từ TypeScript

Xin chào các bạn hôm nay mình xin chia sẽ những tính năng rất hay của TypeScript (TS), các bạn cùng tìm hiểu nhé. Ngoài việc set Type cho biến, tham số hay function thì ví dụ khi bạn nhìn vào một tham

0 0 82