はじめに
オブジェクト指向を学んでいると「カプセル化」という言葉が出てきます。
「内部実装(メソッド)を隠す」「状態(データ)を隠す」などと説明されることがありますが、今回はRubyのコードを通して整理してみます。
privateを使った例
class User
def initialize(name)
@name = format_name(name)
end
def display_name
@name
end
private
def format_name(name)
name.strip.capitalize
end
end
format_name は private なので外から呼べません。
user = User.new("taro")
user.format_name("jiro") # NoMethodError が発生します
名前の整形方法はクラスの内部にあります。
外から見えるのは display_name だけです。
このように、
- 外から使えるメソッド
- 外からは使えないメソッド
が分かれている状態は、カプセル化されていると言えます。
状態を直接変更できる例
class BankAccount
attr_accessor :balance
def initialize(balance)
@balance = balance
end
end
この実装では、
account = BankAccount.new(1000)
account.balance = -100000
が実行でき、クラスの外から内部の状態を書き換えられます。
このように、状態を外から自由に変更できる設計は、カプセル化が弱い状態です。
状態変更をメソッドにまとめた例
class BankAccount
attr_reader :balance # 読み取り専用
def initialize(balance)
@balance = balance
end
def deposit(amount)
raise "金額が不正です" if amount <= 0
@balance += amount
end
def withdraw(amount)
raise "金額が不正です" if amount <= 0
raise "残高不足です" if amount > @balance
@balance -= amount
end
end
ここでは balance は読み取りだけです。
変更は deposit や withdraw を通ります。@balance を外から直接変更することはできません。
正しい操作(メソッド)だけを公開することで、不正な状態が入らないようにできます。
このように、状態変更がクラスの中に閉じている構造は、カプセル化されている状態です。
まとめ
カプセル化とは、
- 外から見せる部分と見せない部分を分けること
- 状態の変更をクラスの中に閉じ込めること
です。
Rubyでは private や attr_reader を使って、外から触れられる範囲をコントロールできます。


コメント