0

Design Pattern Trong Ruby

Design patterns là các giải pháp đã được tối ưu hóa, được tái sử dụng cho các vấn đề lập trình mà chúng ta gặp phải hàng ngày.

Một design patterns không phải là một Class hoặc một Library

Nó là một khuôn mẫu đã được thực hiện. Nó không phải là ngôn ngữ cụ thể nào cả.

Một design patterns có thể thực hiện được ở phần lớn các ngôn ngữ lập trình

Có rất nhiều các Design Pattern khác nhau:

  • Template Method
  • Strategy
  • Observer
  • Composite
  • Iterator
  • Commands
  • Adapter
  • Proxy
  • Decorator
  • Singleton
  • Factory
  • Abstract Factory
  • Builder
  • Interpreter

Dưới đây là 2 trong số chúng

I. Observer Pattern

I.1. Khái niệm

Observer pattern được sử dụng khi xây dựng hệ thống mà ở đó trạng thái của một objectt bị ảnh hưởng bởi trạng thái của một object khác. Excel là một ví dụ hay cho Observer Pattern. Giả sử bạn có một cột các số và có một ô để tính tổng các ô số trong cột đó, thì khi một trong những ô số thay đổi sẽ làm ảnh hưởng, thay đổi ô tính tổng.

I.2. Sử dụng Observer Pattern

Gỉa sử ta có một ứng dụng đơn giản theo dõi tổng số km mà xe đã đi và sẽ thông báo xe cần bảo dưỡng khi xe đã chạy tới một mức nào đó.

Đầu tiên ta sẽ tạo ra một class Notifier như một observer. Và nhất thiết ta phải định nghĩa một update() method bên trongNotifier bởi Module Obserabable sẽ có callback gọi hàm này mỗi khi có đối tượng thay đổi.

class Notifier
  def update(car, miles)
    puts "The car has logged #{miles} miles, totaling #{car.mileage} miles traveled."
    puts "The car needs to be taken in for a service!" if car.service <= car.mileage
  end
end

Mỗi khi observer nhận được thông báo tức là có sự thay đổi thì callback của Obserabable sẽ gọi và in ra thông báo.

Tiếp đến ta sẽ tạo ra một class Car

require 'observer'

class Car
  include Observable

  attr_reader :mileage, :service

  def initialize(mileage = 0, service = 3000)
    @mileage, @service = mileage, service
    add_observer(Notifier.new)
  end

  def log(miles)
    @mileage += miles
    if @mileage >= self.service
    changed
    notify_observers(self, miles)
     end
  end
end

Chạy trên console

2.1.5 :002 > ca = Car.new
 => #<Car:0x0000000230e858 @service=3000, @mileage=0, @observer_peers={#<Notifier:0x0000000230e830>=>:update}>
2.1.5 :003 > ca.log(100)
 => nil
2.1.5 :004 > ca.log(3001)
The car has logged 3001 miles, totaling 3101 miles traveled.
The car needs to be taken in for a service!
 => false
2.1.5 :005 >

II.Singleton Pattern

II.1 Khái niệm

Singleton là một design pattern nó giớ hạn veiejc tạo object của class, chỉ một object được tạo. Nó rất hữu ích khi bạn cần một instance truy cập vào những phần khác nhau của ứng dụng.


class AppConfig
  attr_accessor :data

 @@instance = AppConfig.new

  def self.instance
    return @@instance
  end

  def version
    '1.0.0'
  end

private_class_method :new
end

Ví dụ trên cho thấy ta có thể truy cập vào một instance thông qua một class method chỉ một instance được tạo ra.

II.2 Ruby Single module

Ruby có một module có để thực thi Singleton Patttern đó là Singeleton module. Ta có thể rút gọn lại ví dụ trên bằng việc sử dụng module Singleton

require 'singleton'

class AppConfig
  include Singleton
  attr_accessor :data

  def version
    '1.0.0'
  end
end

2.1.5 :021 > load 'config_singleton.rb'
 => true
2.1.5 :022 > AppConfig.instance.data = {enabled: true}
 => {:enabled=>true}
2.1.5 :023 > AppConfig.instance.version
 => "1.0.0"
2.1.5 :024 > second = AppConfig.instance
 => #<AppConfig:0x00000002017cd0 @data={:enabled=>true}>
2.1.5 :025 > second.data = {enabled: false}
 => {:enabled=>false}
2.1.5 :026 > AppConfig.instance.data
 => {:enabled=>false}

Qua việc chạy trên cho thấy chỉ một instance được tao ra thông qua việc gọi class method instance và được sử dụng global.

Nguồn tham khảo

http://sitepoint.com

http://dalibornasevic.com


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí