Kể từ khi bắt đầu hành trình lập trình, tôi nhận thấy một mô hình thú vị: phần lớn các ứng dụng đều được tạo khuôn mẫu. Vâng, đó là một sự thật thuần túy! Chỉ cần dừng lại ở đây, ở phần đầu của bài viết này và bắt đầu nghĩ về tất cả các dự án bạn đã phát triển.
Họ có đặc điểm gì chung? Nếu quan sát kỹ, bạn sẽ thấy nhiều chức năng cốt lõi được sử dụng lại trong các dự án khác nhau. Các chức năng cốt lõi này thường bao gồm xác thực người dùng, xử lý thanh toán, quản lý người dùng, v.v.
Trong bài viết này, tôi muốn nêu quan điểm rằng tất cả các mẫu này đều đã được các lập trình viên từ xưa tạo ra. Thực sự, hầu hết mọi thứ chúng tôi đang sử dụng hiện nay đều đã được triển khai. Chúng tôi chỉ sửa đổi một số chức năng dựa trên dự án cụ thể.
Tôi sẽ giới thiệu cho bạn các ví dụ từ góc độ phát triển phụ trợ trong Python, nhưng điều này có thể được áp dụng cho bất kỳ ngôn ngữ lập trình hoặc bất kỳ lĩnh vực nào trong lĩnh vực công nghệ phần mềm.
Vậy tất cả các ứng dụng phụ trợ có điểm gì chung? Chúng ta hãy xem xét!
Lưu ý : Nếu bạn đã quen thuộc với OOP (Lập trình hướng đối tượng), hãy coi các mô-đun tạo khuôn mẫu của bạn là mức trừu tượng cao nhất nhưng ở cấp độ ứng dụng để mô-đun này phải được viết theo nguyên tắc này.
Tôi muốn chia nhỏ từng phần tiếp theo thành các thành phần cơ bản, hầu hết có thể áp dụng cho bất kỳ ứng dụng phụ trợ nào.
Thành phần cơ bản
2.1 Mô hình người dùng
Chúng tôi đang xác định lớp User
chung nhất với các thuộc tính có thể áp dụng cho bất kỳ người dùng cụ thể nào.
from werkzeug.security import generate_password_hash, check_password_hash class User: def __init__(self, username, password, email): self.username = username self.password_hash = generate_password_hash(password) self.email = email self.roles = [] def set_password(self, password): self.password_hash = generate_password_hash(password) def check_password(self, password): return check_password_hash(self.password_hash, password)
2.2 Quản lý mã thông báo
Sử dụng JWT để xác thực dựa trên mã thông báo là một lựa chọn tốt về mặt an ninh mạng và các phương pháp hay nhất trong phát triển phụ trợ.
def generate_token(user): payload = { 'username': user.username, 'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1) } return jwt.encode(payload, SECRET_KEY, algorithm='HS256') def verify_token(token): try: payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256']) return payload['username'] except jwt.ExpiredSignatureError: return None except jwt.InvalidTokenError: return None
2.3 Trang trí
from functools import wraps from flask import request, jsonify, session def is_authenticated(func): @wraps(func) def decorated_function(*args, **kwargs): if 'user' not in session: return jsonify({"error": "User not authenticated"}), 401 return func(*args, **kwargs) return decorated_function
def roles_required(*roles): def decorator(func): @wraps(func) def decorated_function(*args, **kwargs): user_roles = session.get('roles', []) if not any(role in user_roles for role in roles): return jsonify({"error": "User does not have the required role"}), 403 return func(*args, **kwargs) return decorated_function return decorator
Và về cơ bản, thế là xong! Bạn có thể sử dụng chức năng được xác định trước này để xác thực trên tất cả các dự án!
Hầu như bất kỳ ứng dụng nào cũng xử lý các giao dịch tài chính. Cho dù đó là một cửa hàng bán thịt ở địa phương hay một doanh nghiệp lớn, bạn sẽ cần sử dụng một hệ thống hiệu quả để thu các khoản thanh toán.
Thành phần cơ bản
Stripe
hoặc PayPal
3.1 Tích hợp cổng thanh toán
Điều này có thể được sử dụng làm cơ sở để tích hợp các cổng thanh toán khác nhau, với việc triển khai cụ thể cho Stripe. Nói chung, sở thích cá nhân của tôi là sử dụng StripeAPI
để thanh toán vì nó đã có mặt từ lâu trên thị trường và thực sự rất dễ tích hợp vào bất kỳ dự án nào.
class PaymentGateway(ABC): @abstractmethod def create_payment_intent(self, amount, currency='gbp'): pass @abstractmethod def confirm_payment(self, payment_id): pass @abstractmethod def handle_webhook(self, payload, sig_header): pass
Đây là ví dụ chung nhất về cổng thanh toán và bạn có thể tập trung vào việc triển khai cụ thể theo nhu cầu của mình.
3.2 Mô hình thanh toán
Xác định các mô hình để lưu trữ thông tin thanh toán. Ví dụ này có thể được điều chỉnh để sử dụng với ORM. Bạn có thể tạo một hệ thống phân cấp lớp phức tạp hơn nếu cần, nhưng đối với ví dụ này, đoạn mã sau là khá đủ.
class Payment: def __init__(self, user_id, amount, currency): self.id = uuid.uuid4() self.user_id = user_id self.amount = amount self.currency = currency self.status = status payments = []
Lưu tất cả các khoản thanh toán vào cơ sở dữ liệu và thiết lập tác vụ Celery
để xử lý các giao dịch, cho phần 3.3. Các bản ghi cơ sở dữ liệu sẽ trông giống như sau:
id | user_id | amount | currency | status --------------------------------------+-----------------------------------+--------+----------+---------- e532d653-7c8b-453a-8cd4-3ab956863d72 | 1ff9efb3-d5e8-4e53-854f-4246ba9ff638 | 100.00 | USD | Failed 35985d41-5d54-4021-bed6-82d7233cc353 | a0984002-bace-478e-b6f9-6e4459e1b5ba | 250.50 | EUR | Pending 1ff9efb3-d5e8-4e53-854f-4246ba9ff638 | 9f896874-dc43-4592-8289-d0f7f8b8583a | 99.99 | GBP | Completed
Bây giờ, chúng tôi đã tạo ra một hệ thống phức tạp có thể được tích hợp vào bất kỳ dự án nào. Bạn vẫn đang theo mô hình này phải không? Điều này có thể được sử dụng MỌI NƠI!
Rốt cuộc, bạn có thể xác định một ứng dụng khác để trực quan hóa dữ liệu này. Bạn đã có quan điểm về việc tạo khuôn mẫu! 😉
Email và thông báo giúp người dùng luôn được cập nhật và tham gia vào hoạt động của ứng dụng của bạn. Cho dù đó là để xác minh tài khoản, đặt lại mật khẩu hay liên lạc tiếp thị thì dịch vụ email đáng tin cậy đều cần thiết cho bất kỳ loại dự án nào.
SendGrid
hoặc Amazon SES
.
4.1 Tích hợp dịch vụ email
Xác định logic chính của SendGrid
để gửi email bên trong lớp EmailService
.
import sendgrid from sendgrid.helpers.mail import Mail class EmailService: def __init__(self, api_key): self.sg = sendgrid.SendGridAPIClient(api_key) def send_email(self, from_email, to_email, subject, html_content): email = Mail( from_email=from_email, to_emails=to_email, subject=subject, html_content=html_content ) try: response = self.sg.send(email) return response.status_code except Exception as e: return str(e)
Cũng như cổng thanh toán, bạn không cần tập trung vào bất kỳ tiện ích hoặc sản phẩm cụ thể nào trên thị trường. Đây chỉ là một ví dụ về cách nó có thể được khái quát hóa và tạo khuôn mẫu cho bất kỳ dự án nào.
4.2 Mẫu email
Mẫu yêu thích của tôi cho các hệ thống như thế này là mẫu trình xử lý; bạn chỉ cần thêm ngày càng nhiều khóa vào từ điển dưới dạng một loại email và đường dẫn đến tệp có nội dung.
email_templates = { 'welcome': “welcome.html”, 'reset_password': "<h1>Reset Your Password</h1><p>Click <a href='{link}'>here</a> to reset your password.</p>" }
Mặt khác, có thể tốt hơn nếu xác định Enum
cho cùng mục đích.
4.3 Gửi email
Chúng ta cần một chức năng để biến điều kỳ diệu thành hiện thực! Hãy viết như sau:
def send_email(email_service, from_email, to_email, subject, template_name, **template_vars): """ Send an email using the specified email service. """ html_content = get_email_template(template_name, **template_vars) return email_service.send_email(from_email, to_email, subject, html_content)
Một điểm quan trọng khác là thêm một số tệp vào tất cả các dự án phụ trợ, chẳng hạn như README
.env
config.py
, pyproject.toml,
.pre-commit.yml
và đưa ra cấu trúc cơ sở của các tệp bên trong dự án.
Mặc dù cấu trúc được đề xuất hơi chặt chẽ hơn một chút đối với việc triển khai Python, nhưng như tôi đã đề cập trước đó, bạn có thể thực hiện tương tự với bất kỳ ngôn ngữ hoặc lĩnh vực nào khác.
Cũng cần lưu ý rằng việc tạo khuôn mẫu ở mức trừu tượng cao nhất và duy trì cấu trúc tốt của ứng dụng có thể
được sử dụng lại cho các dự án khác dưới dạng gói hoặc phần bổ sung cho kiến trúc microservice.
MỌI THỨ CÓ THỂ ĐƯỢC TẠM THỜI!
Các ví dụ được cung cấp ở đây chỉ là bước khởi đầu—những mẫu này có thể được mở rộng và cải tiến để bao gồm các tình huống phức tạp hơn khi dự án của bạn phát triển. Bạn có thể thêm caching
thiết lập k8s
, docker
, cơ sở hạ tầng Devops
, CI/CD
và đường ống.
Hãy nhớ một câu nói đơn giản: Khi bạn đã hoàn thành tốt công việc của mình, bạn có thể sử dụng công việc tương tự trong khi hoàn thành công việc khác.
Mục tiêu là làm cho dự án, cơ sở hạ tầng, thành phần và dịch vụ có thể tái sử dụng được trên các ứng dụng khác nhau!
Hãy pha cho mình một tách trà và suy nghĩ xem phần nào trong ứng dụng của bạn có thể được sử dụng lại trong các ứng dụng khác nhau. Hãy thử tạo các dịch vụ tương tự và tự động hóa công việc của bạn, chỉ điều chỉnh một số đoạn mã!
Cảm ơn bạn đã đọc và chúc bạn tạo mẫu vui vẻ!