1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

プログラマはドメインの実装に集中すべき

Posted at

1. Ruby(直感的・シンプル)

Rubyではクラスがそのままオブジェクトなので、非常にスッキリ書けます。
Ruby

class PaymentFactory
def self.create(type)
case type
when :credit then CreditPayment.new
when :cash then CashPayment.new
end
end
end

利用側:クラス名すら知らなくていい
payment = PaymentFactory.create(:credit)
payment.pay(100)

「newして返すだけ」という直感。リファクタリングもクラスの中身を書き換えるだけで済みます。]

2. Go(構造体が必要な「あいたた」例)

Goにはクラスがないため、**「メソッドをまとめるための構造体」を定義し、さらに「インターフェース」**を定義する必要があります。
Go

type Payment interface {
Pay(amount int)
}

// メソッドしか必要なくても、空の構造体が必要
type CreditPayment struct{}
func (p CreditPayment) Pay(amount int) { /* ... */ }

type CashPayment struct{}
func (p CashPayment) Pay(amount int) { /* ... */ }

// Factory関数
func NewPayment(t string) Payment {
switch t {
case "credit":
return CreditPayment{} // 構造体のインスタンス化が必要
case "cash":
return CashPayment{}
default:
return nil
}
}
「関数だけでいいのに、インターフェースを満たすために空の構造体を作らされる」という手間が発生します。

3. Rust(型と所有権の壁)

Rustはさらに厳格です。Factoryから「動的に異なる型」を返す場合、メモリサイズを確定させるために Box(ポインタ)が必要になります。
Rust

trait Payment {
fn pay(&self, amount: u32);
}

struct CreditPayment; // 空の構造体
impl Payment for CreditPayment {
fn pay(&self, amount: u32) { /* ... */ }
}

struct CashPayment;
impl Payment for CashPayment {
fn pay(&self, amount: u32) { /* ... */ }
}

// Factory:Box という魔法の呪文が必要
fn create_payment(t: &str) -> Box {
match t {
"credit" => Box::new(CreditPayment),
"cash" => Box::new(CashPayment),
_ => panic!("Unknown"),
}
}

プログラムはドメインの機能に集中すべきであり、なるべくシンプルな方法を選ぶべきで余計なことに気を使う必要はない

1
1
8

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?