Excapsulation

What is “Excapsulation”

Encapsulation is a fundamental concept in object-oriented programming (OOP) that refers to the bundling of data and the methods that act on that data into a single unit called a class.

Encapsulation enables the programmer to hide the implementation details of the class from the outside world and provide a clean and well-defined interface for accessing and modifying the data.

By encapsulating data and methods within a class, we can ensure that the data is accessed and modified only through the methods provided by the class, thereby preventing unauthorized access and manipulation of the data.

In other words, encapsulation provides data protection and promotes data integrity by preventing accidental modification of data by other parts of the program.

Example

In addition to attr_reader, attr_writer, and attr_accessor, see example here. Ruby offers other ways to achieve encapsulation.

One way is to use the private and protected keywords to restrict method access. For example, we can make some methods private or protected to limit external access:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Person
  def initialize(name, age)
    @name = name
    @age = age
  end

  def name
    @name
  end

  def age
    @age
  end

  def age=(new_age)
    validate_age(new_age)
    @age = new_age
  end

  def greet
    puts "Hello, my name is #{@name} and I am #{@age} years old."
  end

  private

  def validate_age(age)
    raise "Invalid age" unless age.is_a?(Integer) && age > 0
  end
end

In the example above, we made the validate_age method private to limit external access. We can also make the greet method public to allow external calling.

Another way is to use module to create namespaces and encapsulate classes. For example, we can put some related methods into a module and include them in the class:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
module Validation
  def validate_age(age)
    raise "Invalid age" unless age.is_a?(Integer) && age > 0
  end
end

class Person
  include Validation

  def initialize(name, age)
    @name = name
    @age = age
  end

  def name
    @name
  end

  def age
    @age
  end

  def age=(new_age)
    validate_age(new_age)
    @age = new_age
  end

  def greet
    puts "Hello, my name is #{@name} and I am #{@age} years old."
  end
end

In the example above, we put the validate_age method into the Validation module and include it in the Person class. This way, we can validate the age property of Person objects by calling the validate_age method while keeping the interface of the class concise and clear.

In Ruby, there are three common ways to encapsulate code: defining class attributes using attr_reader, attr_writer, and attr_accessor methods, limiting method access using the private and protected keywords, and grouping related methods and creating namespaces using module. These techniques can help us better encapsulate our code, improve its readability, maintainability, and reusability.

Extended reading

include vs extend

封裝是什麼

封裝是物件導向程式設計(OOP)中的一個基本概念,指將數據和作用於數據的方法打包成一個單元,稱為類別。

封裝使得程式設計師可以隱藏類別的實現細節,為外部世界提供一個清晰且明確的介面,以便存取和修改數據。

透過封裝,我們可以確保數據只能透過類別提供的方法進行存取和修改,從而防止未經授權的存取和操作數據。

換句話說,封裝提供了數據保護,並通過防止程序中其他部分意外修改數據來促進數據完整性。

範例

除了之前介紹過的 attr_reader、attr_writer 和 attr_accessor 之外 範例在這,Ruby 還有其他方式來實現封裝。

一種方式是使用 private 和 protected 關鍵字來限制方法的訪問權限。例如,我們可以將某些方法設為私有方法或保護方法,以限制外部的訪問:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Person
  def initialize(name, age)
    @name = name
    @age = age
  end

  def name
    @name
  end

  def age
    @age
  end

  def age=(new_age)
    validate_age(new_age)
    @age = new_age
  end

  def greet
    puts "Hello, my name is #{@name} and I am #{@age} years old."
  end

  private

  def validate_age(age)
    raise "Invalid age" unless age.is_a?(Integer) && age > 0
  end
end

在上面的例子中,我們將 validate_age 方法設為私有方法,以限制外部的訪問。此外,我們還可以將 greet 方法設為公共方法,以允許外部調用。

另一種方式是使用 module 來創建命名空間和封裝類。例如,我們可以將一些相關的方法放在一個模組中,並將它們導入到類中:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
module Validation
  def validate_age(age)
    raise "Invalid age" unless age.is_a?(Integer) && age > 0
  end
end

class Person
  include Validation

  def initialize(name, age)
    @name = name
    @age = age
  end

  def name
    @name
  end

  def age
    @age
  end

  def age=(new_age)
    validate_age(new_age)
    @age = new_age
  end

  def greet
    puts "Hello, my name is #{@name} and I am #{@age} years old."
  end
end

在上面的例子中,我們將 validate_age 方法放在 Validation 模組中,並將其包含到 Person 類中。這樣,我們可以通過調用 validate_age 方法來驗證 Person 對象的年齡屬性,同時保持類的接口簡潔和清晰。

所以在Ruby中,有三種常見的封裝方式:使用attr_reader、attr_writer、attr_accessor等方法定義類的屬性、使用private和protected關鍵字來限制方法的訪問權限,以及使用module來創建命名空間和將相關的方法分組。這些技巧可以幫助我們更好地封裝代碼,提高代碼的可讀性、可維護性和可重用性。

延伸

include vs extend

updatedupdated2023-03-022023-03-02