پترن Typeclass ویا adhoc polymorphism

فرض کنید ما چند نوع داده داریم که میخواهیم به json تبدیل کنیم و توسط کافکا بفرستیم

case class Person(name: String, age: Int)
case class Book(name: String, author: String)

راه حل OO:
ساختن interface و inheritance

trait Encoder {
 def toJson: Json
}
case class Person(name: String, age: Int) extends Encoder {
  def toJson = " { \"name\": \"${name}\", age: ${age}
  }
  "
}
object KafkaPublisher {
  def publish(encoder: Encoder): Unit = {
    KafkaProducer.send("topic" encoder.toJson)
  }
}

مشکل ها با این روش:
۱. پیچیدگی ارث بری
۲. خیلی مواقع ما به داده دسترستی نداریم که interface برایش بنویسیم و باید در object دیگه بصورت مصنوعی ابجکت رو بپوشینیم
۳. داده و عملکرد خیلی به هم coupling دارند

راه حل functional:

داده رو از عملکرد موردنظر جدا میکنیم
و به صورت generic برای هر تایپ تعریف میکنیم

trait Encoder[A] {
  def toJson(a: A): Json
}
object KafkaPublisher {
  def publish[A](a: A)(implicit encoder: Encoder[A]): Unit = {
    KafkaProducer.send("topic" encoder.toJson(a))
  }
}

حالا برنامه کافکا برای همه ی داده ها کار میکنه تا زمانی که Encoder برای آنها تعریف بشه این داده میتونه در کتابخانه ای باشه که ما اصلا تا به حال ندیدیم
اما هروقت نیاز داشته باشیم کافیه که Encoder برای آن تعریف کنیم

5 Likes

درود سام عزیز من هیچی نفهمیدم قطعه کد های الیکسیر در این مورد می تونی مثال بزنی ؟

1 Likes

درود شهریار عزیز این شبیه
protocol ها در الیکسیر هست یا extension و protocol در سویفت

4 Likes

بنظر میاد که تیتر مطلب جای بهتر شدن داره چون توضیح زیادی در مورد تایپ کلس توش نیست و مثال ها خیلی به کیس کلس های اولی(Book, Person) ربطی ندارند :smiling_imp:

بله case class هیچ ارتباطی به typeclass که پترن adhoc polymorphism هست نداره typeclass از هسکل ریشه می‌گیره
http://learnyouahaskell.com/types-and-typeclasses

2 Likes

متوجه هستم، اما منظورم بیشتر همون‌تیتر بود و اینکه خوب بود اگر توضیحی اولیه در مورد تایپ کلس داشتیم، چون خیلی امکان قدرتمندیه که دست کم‌گرفته میشه.

2 Likes