Aku terbaca satu artikel Would Your Objects Praise You?
cuma aku kurang setuju dengan apa yang mamat nie cakap. Ada benarnya tapi tak semuanya betul konsep tu. Apa yang cuba disampaikan ialah konsep Single Responsibility Principal.
The single responsibility principle states that every object should have a single responsibility, and that all its services should be narrowly aligned with that responsibility. [Wikipedia].
Ok, cara dan formula yang di gunakan cukup menarik dan bagus dan aku pun rasa sesuatu yang reasonable unutk digunakan apabila buat domain model anlysis. Formula yang cuba diketengahkan ialah
Can a [type] [action in the infinitive] itself?
So dalam artikel tersebut , mamat nie ambil contoh sebuah kereta
Jadi berdasarkan method yang ada pada kereta tersebut kalau dilihat memang menyalahi SRP. Sebab class Car coupling dengan telalu banyak kerja yang perlu dilakukan. Cuba fikirkan sejenak apa tugas sebuah kereta. Jawapan dia abstract dan berlainan bagi setiap orang, sebab itu SRP nie kalau mengikut pencetus principle yang dekenali sebagai Pakcik Bob pattern yang simple tapi susah untuk dapat yang betul betul ngam.
"The SRP is one of the simplest of the principle, and one of the hardest to get right. Conjoining responsibilities is something that we do naturally. Finding and separating those responsibilities from one another is much of what software design is really about".
Berbalik semula kepada persoalan kereta tadi. Mamat Brian nie cadangkan untuk dapatkan cara yang betul penggunaan SRP ialah dengan melakukan pertanyaan seperti berikut:
- Can a car change gears by itself?
- Can a car change a radio station by itself?
- Can a car drive itself?
- Can a car idle by itself?
- Can a car park itself?
- Can a car start itself?
Unless you’re the lucky owner of the Knight Rider, you probably answered ‘NO’ to a few of these questions. For every question or observation you have answered ‘NO’, you should more than likely refactor the class and move some of its responsibilities elsewhere. But where exactly can you move these responsibilities? Well, before we dive to some of these answers, let’s see if we can directly some of the original questions pertaining to our Car class:
- Can a car change gears by itself? ANSWER: Sure, if it has an automatic transmission. Otherwise, only the driver can shift gears.
- Can a car change a radio station by itself? ANSWER: Nope, only the driver (or the passenger) can change the radio station.
- Can a car drive itself? ANSWER: Not unless it’s KITT! Only a driver can drive a car.
- Can a car idle by itself? ANSWER: Sure it can.
- Can a car park itself? ANSWER: Nope! Only a driver can know how to park a car.
- Can a car start itself? ANSWER: Uh, no. Once again, only the driver can start the car.
Disini kena faham konsep message to object. Persoalan Driver perlu ada atau tidak masih lagi abstract kepada Domain Expert dan juga untuk apa application ini dihasilkan. Kalau application nie dihasilkan untuk stimulate Video Game dimana dari screen hanya nampak kereta yang boleh dipandu maka class Driver tidak diperlukan sebaliknya class Driver itu digantikan dengan Application Service - CarService.
Ini pula pada pendapat aku, yang dikategorikan sebagai programmer kampung. Untuk mengikut konsep SRP kita perlu pecahkan tugas-tugas tersebut kepada yang berhak, jangan tamak nak ambil tugas orang lain, nasib baik BIJAN tak tamak dia ambik sikit je. Dari class Car kita akan pecahkan kepada class Gear, class Radio, class Engine.
//Car.cs
public class Car
{
public Gear Gear { set; get; }
public Engine Engine { set; get; }
public Radio Radio { set; get; }
public void Drive()
{
}
}
//Engine.cs
public class Engine
{
public void Start()
{
}
}
//Gear.cspublic class Gear
{
public void ChangeGear()
{
}
}
//Radio.cspublic class Radio
{
public void ChangeRadioStation()
{
}
}
//CarService.cs
public class CarService
{
public Car Car { set; get; }
public void ChangeGear()
{
Car.Gear.ChangeGear();
}
public void ChangeRadioStation()
{
Car.Radio.ChangeRadioStation();
}
public void StartEngine()
{
Car.Engine.Start();
}
public void Drive()
{
Car.Drive();
}
}
