07/09/2018, 16:04

Giải thích tính năng Duck Typing của Ruby dưới lăng kính 4OOP

Ruby vẫn luôn được coi là ngôn ngữ rất hướng đối tượng, vì trong Ruby mọi thứ đều là object. Theo bài 4 tính chất đặc thù của lập trình hướng đối tượng, có thể viết chương trình Ruby để thể hiện 4 tính chất ấy. Tuy nhiên, nếu đã có căn bản Ruby, thì chắc bạn đã để ý là không như những ngôn ngữ ...

alt text

Ruby vẫn luôn được coi là ngôn ngữ rất hướng đối tượng, vì trong Ruby mọi thứ đều là object. Theo bài 4 tính chất đặc thù của lập trình hướng đối tượng, có thể viết chương trình Ruby để thể hiện 4 tính chất ấy. Tuy nhiên, nếu đã có căn bản Ruby, thì chắc bạn đã để ý là không như những ngôn ngữ ví dụ như Java, Ruby không có từ khóa để thể hiện một cách tường minh tính trừu tượng (từ khóa trong Java: interface) và đa hình (từ khóa trong Java: override).

Có thể giải thích lí do của việc trên, là Ruby có tính năng gọi là Duck Typing để thay thế.

Ta hãy thử làm bài tập 4OOP để sáng tỏ:

class Animal
  attr_reader :name

  def initialize(name)
    @name = name
  end

  def say_hello
    raise 'Subclasses should implement this method'
  end
end

class Cat < Animal
  def say_hello
    puts "Meow, my name is #{name}"
  end
end

class Dog < Animal
  def say_hello
    puts "Woof woof, my name is #{name}"
  end
end

class Duck
  def initialize(name)
    @name = name
  end

  def say_hello
    puts "Trump, my name is #{name}"
  end
end

class Zoo
  def initialize
    @animals = []
  end

  def add(animal)
    @animals << animal
  end

  def say_hello_all
    @animals.each { |a| a.say_hello }
  end
end

# Some test
z = Zoo.new
z.add(Cat.new('Kitty'))
z.add(Dog.new('Pluto'))
z.add(Duck.new('Donald'))
z.say_hello_all

Chạy thử sẽ thấy các con vật chào hỏi ngon lành.

Tuy nhiên, để ý sẽ thấy:

  • Duck không thừa kế từ Animal. Trong các ngôn ngữ như Java, ta phải định nghĩa interface có phương thức say_hello, để các con vật trong Zoo có chung interface. Còn trong Ruby thì miễn là Duck có phương thức có cùng tên là ta có thể nhét chung với các Animal khác. Ý tưởng của Duck Typing là: Vịt trắng vịt đen đều là vịt, thậm chí bất kể con gì đi như vịt nói như vịt cũng đều có thể coi là vịt.
  • Cat và Dog thừa kế phương thức say_hello, và override lại phương thức say_hello của Animal. Nhưng Ruby không có từ khóa override như các ngôn ngữ như Java để thể hiện tường minh chỗ này. Việc này có lẽ nằm trong ý đồ thiết kế của Ruby, là trung thành với ý tưởng Duck Typing. Bạn cũng có thể bỏ say_hello trong Animal đi mà chương trình vẫn chạy tốt.

Hai phân tích ở trên cho thấy mặc dù Duck Typing làm cho Ruby rất uyển chuyển, nhưng vì Ruby không bắt buộc phải định rõ interface và override, để chương trình rõ ràng để những lập trình viên cùng tham gia viết chương trình có thể làm việc suôn sẻ với nhau, trong chương trình cần phải cẩn thận viết comment những chỗ mang tính trừu tượng và đa hình. Nếu không, chỉ cần chương trình to to một chút và vài người cùng viết, thì mã nguồn sẽ thành đống bùi nhùi lúc nào không hay.

0