ダックタイピングとは?
ダックタイピングはRubyのような動的型付け言語でよく使われるプログラミングの概念です。この概念は、「もしオブジェクトがカモのように歩き、カモのように鳴くなら、そのオブジェクトはカモである」という考え方に基づいています。つまり、オブジェクトの型よりも、そのオブジェクトがどのようなメソッドを持っているか(どのように「振る舞う」か)が重要とされます。
# オブジェクトの型よりも、そのオブジェクトがどのようなメソッドを持っているか
# Duck, Lion, Sheep, Zekromはそれぞれquackというメソッド・振る舞いを持っている状態
class Duck
def quack
"クワ!"
end
end
class Lion
def quack
"ガオー"
end
end
class Sheep
def quack
"メェメェ"
end
end
class Zekrom
def quack
"ババリバリッシュ!!"
end
end
duck = Duck.new
lion = Lion.new
sheep = Sheep.new
zekrom = Zekrom.new
animals = [duck, lion, sheep, zekrom]
animals.each do |animal|
puts animal.quack
end
# => "クワ!"
# => "ガオー"
# => "メェメェ"
# => "ババリバリッシュ!!"
class Duck
def quack
"クワ!"
end
end
class Lion
def roar
"ガオー"
end
end
class Sheep
def bleat
"メェメェ"
end
end
class Zekrom
def scream
"ババリバリッシュ!!"
end
end
# ダックタイピングが存在しない場合、新しい動物クラスを追加するたびに、make_animal_soundメソッドに対する変更が必要になるというデメリットが発生
def make_animal_sound(animal)
if animal.is_a?(Duck)
puts animal.quack
elsif animal.is_a?(Lion)
puts animal.roar
elsif animal.is_a?(Sheep)
puts animal.bleat
elsif animal.is_a?(Zekrom)
puts animal.scream
else
puts "未知の動物です"
end
end
# それぞれのクラスのインスタンスを作成
duck = Duck.new
lion = Lion.new
sheep = Sheep.new
zekrom = Zekrom.new
# 関数を呼び出す
make_animal_sound(duck)
make_animal_sound(lion)
make_animal_sound(sheep)
make_animal_sound(zekrom)
なぜ、新しい動物クラスを追加するたびにmake_animal_soundメソッドを変更する必要があることがデメリットになるのか?
保守性の低下
プログラムに新しい機能を追加するたびに、既存の関数やメソッドを変更する必要があると、そのコードは保守しにくくなる。特に大きなプロジェクトや多くの開発者が関わるプロジェクトでは、一箇所の変更が他の部分に予期せぬ影響を与える可能性があるため。
スケーラビリティの問題
システムが成長し、新しいタイプの動物が頻繁に追加される場合、そのたびに中央のmake_animal_soundメソッドを更新する必要がある。これはソースコードが複雑になり、ソフトウェアの拡張性に問題が出る(Aを変更したら、BやCを変更しなければならないが、そんなの覚えてないので、改修漏れが起きる)
オープン/クローズド原則の違反
「拡張に対して開かれているべきであり、変更に対しては閉じているべき」だが、case文の追加をする必要があるため、既存のコードの変更に対しては閉じているべき(=変更せずにいられるべき)に反する。
参考
https://qiita.com/zizynonno/items/4aed159690b74c84d058
エラー発生の可能性
既存のメソッドを頻繁に変更すると、新しいバグの導入や既存の機能の破壊のリスクが高まる。テストカバレッジが不十分な場合、これらのエラーは発見されにくい。
ダックタイピングを使用すると、これらの問題を大幅に軽減できる。各クラスは独立して同じインターフェース(この例ではquackメソッド)を実装するため、新しい動物クラスを追加しても中央のメソッドを変更する必要がない。これにより、システムの拡張性が向上し、保守性が高まる。