Modules và Mix-ins trong Ruby on rails
This post hasn't been updated for 5 years
Giới thiệu
Đây là những chủ đề cũ, không mới đối với các lập trình viên. Hôm nay trong bài viết này tôi muốn chia sẻ vai trò của các mô-đun và mix-in trong Ruby on Rails.
Ngày nay nhiều lập trình viên phát triển rất nhiều chương trình. Độ dài của chương trình là không thể biết trước được. Nhưng những đoạn code đó không phải lúc nào cũng là duy nhất trong chương trình. Có một số trường hợp trong đó một đoạn code được sử dụng nhiều lần. Bởi vì việc các đoạn code được gọi lại nhiều lần, các phương thức được sử dụng nhiều lần, ví dụ: trong một chương trình như dự án thương mại điện tử, cổng thanh toán phải được đặt trên nhiều nơi, bởi vì trong trang web đó, đối với mỗi sản phẩm mà người dùng mua thì cần phải thanh toán và sau đó nhận được sản phẩm. Vì vậy, code giao diện cổng thanh toán này phải được đặt trên nhiều sản phẩm trong trang web. Vì vậy, trong những trường hợp như vậy, chúng ta cần một khái niệm ngôn ngữ lập trình cho phép tính năng viết code tại một nơi và cho phép truy cập vào nhiều nơi trong dự án.
Các ngôn ngữ lập trình tương tự như là Java, Python sẽ đưa ra giải pháp cho vấn đề của mình thông qua các tính năng của nó như đa hình, kế thừa, interfaces,...
Trước khi bắt đầu tìm hiểu vai trò của các mô-đun và Mix-in, mình sẽ giới thiệu chi tiết cho bạn các khái niệm đó.
Class: Một lớp chỉ đơn giản là tập hợp các phương thức, biến. Ở đây, tên lớp được thêm tiền tố với một từ khóa class.
Ở đây các module giống với class, chứa một tập hợp các biến, phương thức, hàm,... Mỗi mô-đun phải được thêm tiền tố với từ khóa module.
Các mô-đun là một cách để nhóm các phương thức, lớp và hằng số lại với nhau. Các mô-đun cung cấp cho bạn hai lợi ích chính.
- Các mô-đun cung cấp một namespace và ngăn chặn xung đột tên.
- Các mô-đun thực hiện các cơ sở mixin.
Cú pháp
module Identifier
statement1
statement2
...........
end
Các hằng số mô-đun được đặt tên giống như các hằng lớp, với một chữ cái viết hoa ban đầu. Các định nghĩa phương thức trông cũng tương tự: Các phương thức mô-đun được định nghĩa giống như các phương thức lớp.
Như với các phương thức lớp, bạn gọi một phương thức mô-đun bằng cách đặt trước tên của nó với tên của mô-đun và bạn tham chiếu một hằng số bằng cách sử dụng tên mô-đun và hai dấu hai chấm.
Ví dụ
#!/usr/bin/ruby
# Module defined in trig.rb file
module Trig
PI = 3.141592654
def Trig.sin(x)
# ..
end
def Trig.cos(x)
# ..
end
end
Chúng ta có thể định nghĩa thêm một mô-đun có cùng tên chức năng nhưng chức năng khác nhau
#!/usr/bin/ruby
# Module defined in moral.rb file
module Moral
VERY_BAD = 0
BAD = 1
def Moral.sin(badness)
# ...
end
end
Giống như các phương thức lớp, bất cứ khi nào bạn định nghĩa một phương thức trong một mô-đun, bạn chỉ định tên mô-đun theo sau là một dấu chấm và sau đó là tên phương thức.
Lệnh require trong Ruby
Câu lệnh yêu cầu tương tự như câu lệnh trong C và C ++ và câu lệnh import của Java. Nếu một chương trình thứ ba muốn sử dụng bất kỳ mô-đun được xác định nào, nó chỉ có thể tải các tệp mô-đun bằng cách sử dụng câu lệnh Ruby require
Cú pháp
require filename
Ví dụ
$LOAD_PATH << '.'
require 'trig.rb'
require 'moral'
y = Trig.sin(Trig::PI/4)
wrongdoing = Moral.sin(Moral::VERY_BAD)
Ở đây chúng ta đang sử dụng $LOAD_PATH << '.'
để làm cho Ruby biết rằng các tệp được bao gồm phải được tìm kiếm trong thư mục hiện tại. Nếu bạn không muốn sử dụng $LOAD_PATH thì bạn có thể sử dụng require_relative để bao gồm các tệp từ một đường dẫn thư mục tương đối.
Lệnh include trong Ruby
Bạn có thể nhúng một mô-đun trong một lớp. Để nhúng một mô-đun vào một lớp, bạn sử dụng câu lệnh include trong lớp
Cú pháp
include modulename
Nếu một mô-đun được định nghĩa trong một tệp riêng biệt, thì bắt buộc phải include tệp đó bằng cách sử dụng câu lệnh require trước khi nhúng mô-đun vào một lớp.
Ví dụ
Hãy xem xét các mô-đun sau được viết trong tệp support.rb
module Week
FIRST_DAY = "Sunday"
def Week.weeks_in_month
puts "You have four weeks in a month"
end
def Week.weeks_in_year
puts "You have 52 weeks in a year"
end
end
Bây giờ, bạn có thể include mô-đun này trong một lớp như sau
#!/usr/bin/ruby
$LOAD_PATH << '.'
require "support"
class Decade
include Week
no_of_yrs = 10
def no_of_months
puts Week::FIRST_DAY
number = 10*12
puts number
end
end
d1 = Decade.new
puts Week::FIRST_DAY
Week.weeks_in_month
Week.weeks_in_year
d1.no_of_months
Điều này sẽ tạo ra kết quả sau đây
Sunday
You have four weeks in a month
You have 52 weeks in a year
Sunday
120
Mixins trong Ruby
Trước khi đi qua phần này, chúng ta giả sử đã có kiến thức về các khái niệm hướng đối tượng.
Khi một lớp có thể kế thừa các tính năng từ nhiều hơn một lớp cha, lớp đó có nghĩa vụ hiển thị đa kế thừa.
Ruby không hỗ trợ đa kế thừa trực tiếp nhưng Ruby Modules có một công dụng tuyệt vời khác. Để làm được điều đó ruby cung cấp một phương tiện gọi là mixin.
Mixins cung cấp cho bạn một cách kiểm soát tuyệt vời để thêm chức năng cho các lớp. Tuy nhiên, sức mạnh thực sự của chúng xuất hiện khi mã trong mixin bắt đầu tương tác với mã trong lớp sử dụng nó.
Hãy cùng thực thi đoạn code sau đây để hiểu về mixin
module A
def a1
end
def a2
end
end
module B
def b1
end
def b2
end
end
class Sample
include A
include B
def s1
end
end
samp = Sample.new
samp.a1
samp.a2
samp.b1
samp.b2
samp.s1
Mô-đun A bao gồm các phương thức a1 và a2. Mô đun B bao gồm các phương thức b1 và b2. Lớp Smaple bao gồm cả hai mô-đun A và B. Lớp Sample có thể truy cập cả bốn phương thức, cụ thể là a1, a2, b1 và b2. Do đó, bạn có thể thấy rằng lớp Sample kế thừa từ cả hai mô-đun. Vì vậy, bạn có thể nói lớp Sample hiển thị đa kế thừa hoặc một mixin.
All Rights Reserved