0
0
Lập trình
NM

Các Design Patterns Quan Trọng Bạn Nên Nắm Vững Trong Lập Trình Web

Đăng vào 1 tuần trước

• 3 phút đọc

Chủ đề:

DesignPattern

Giới Thiệu

Việc phát triển ứng dụng web thường đòi hỏi sự hỗ trợ từ các framework và thư viện. Mặc dù chúng cung cấp cấu trúc và quy tắc rõ ràng, nhưng đôi khi bạn vẫn cảm thấy bối rối trong việc tổ chức mã nguồn. Bài viết này sẽ giới thiệu một số design patterns quan trọng mà bạn nên nắm vững, kèm theo ví dụ cụ thể bằng ngôn ngữ Ruby.

1. Service Object

Trong mô hình MVC (Model-View-Controller), controller đóng vai trò làm cầu nối giữa model và view. Dù vậy, không nên để controller chứa quá nhiều logic. Thay vào đó, bạn hãy tách các logic đó ra thành một service riêng biệt:

Ví dụ mà không có service:

ruby Copy
class UsersController
  def create
    user = User.new(user_params)

    if user.save
      UserMailer.verify_email(user)
      render json: { status: :success, user: user.as_json }
    else
      render json: { status: :error, errors: user.errors.messages }
    end
  end
end

Ví dụ khi sử dụng service:

ruby Copy
class CreateUserService
  def initialize(user_params)
    @user = User.new(user_params)
  end

  def execute
    return error_response unless @user.save
    send_verify_email
    success_response
  end

  private

  attr_reader :user

  def success_response
    ServiceResponse.success(payload: @user.as_json)
  end

  def error_response
    ServiceResponse.error(payload: @user.errors.messages)
  end

  def send_verify_email
    UserMailer.verify_email(@user)
  end
end
ruby Copy
class UsersController
  def create
    render json: CreateUserService.new(user_params).execute
  end
end

2. ServiceResponse

Khi bạn có nhiều service trong dự án, việc đồng nhất định dạng dữ liệu trả về là rất quan trọng. Ví dụ, bạn có thể sử dụng ServiceResponse để tạo một cấu trúc dữ liệu đồng nhất:

ruby Copy
class ServiceResponse
  def self.success(message: nil, payload: {})
    { status: :success, message: message, payload: payload }
  end

  def self.error(message: nil, payload: {})
    { status: :error, message: message, payload: payload }
  end
end

Sử dụng ServiceResponse trong service:

ruby Copy
class CreateUserService
  # ...

  def execute
    return error_response unless @user.save
    send_verify_email
    success_response
  end

  private

  def success_response
    ServiceResponse.success(payload: @user.as_json)
  end

  def error_response
    ServiceResponse.error(payload: @user.errors.messages)
  end
end

3. Finder

Finder giúp bạn thực hiện các thao tác truy vấn cơ sở dữ liệu một cách gọn gàng hơn. Việc sử dụng finder giúp giảm thiểu khối lượng logic trong controller và cho phép tái sử dụng dễ dàng:

Ví dụ không có finder:

ruby Copy
class EmployeesController < ApplicationController
  def index
    @employees = current_user.employees
    @employees = @employees.id_in(params[:id]) if params[:id].present?
  end
end

Ví dụ với finder:

ruby Copy
class EmployeesFinder
  def initialize(manager, params)
    @manager = manager
    @params = params
  end

  def execute
    employees = @manager.employees
    employees = filter_by_id(employees)
    employees = filter_by_name(employees)
    employees = filter_by_blocked(employees)
    order(employees)
  end

  private

  # Các phương thức filter_by_id, filter_by_name và filter_by_blocked 
end

Sử dụng finder trong controller:

ruby Copy
class EmployeesController < ApplicationController
  def index
    @employees = EmployeesFinder.new(current_user, params).execute
  end
end

4. Decorator

Decorator cho phép bạn định dạng hoặc thêm các thông tin khác cho một record mà không làm phình to model:

Ví dụ sử dụng decorator:

ruby Copy
class UserDecorator
  def formatted_created_at
    @user.created_at.strftime('%Y/%m/%d')
  end
end

5. Presenter

Presenter giúp bạn quản lý logic phức tạp trong controller và view dễ dàng hơn. Khi sử dụng presenter, bạn có thể giảm số lượng biến instance trong controller:

Ví dụ:

ruby Copy
class PostPresenter
  def initialize(current_user, post)
    @current_user = current_user
    @post = post
  end

  # Các phương thức để lấy thông tin
end

6. Serializer

Serializer thường được sử dụng để định dạng phản hồi cho API, đảm bảo rằng dữ liệu được trả về có cấu trúc rõ ràng.

Ví dụ sử dụng serializer:

ruby Copy
class PostSerializer < ActiveModel::Serializer
  attributes :id, :title, :content
end

Kết Luận

Trên đây là một số design patterns quan trọng mà bạn nên tìm hiểu và áp dụng vào quá trình lập trình web. Việc lựa chọn đúng pattern giúp mã nguồn trở nên rõ ràng, dễ quản lý và mở rộng trong tương lai.
source: viblo

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào