"Hai, Amigo!"

"Hai, Bilaabo!"

"Topik kami hari ini bukan sahaja menarik - ia akan menjadi sangat epik."

"Hari ini saya akan memberitahu anda apakah corak reka bentuk. "

"Cool! Saya telah mendengar banyak tentang mereka. Saya tidak sabar!"

"Pengaturcara yang berpengalaman perlu menulis banyak kelas. Tetapi bahagian yang paling sukar dalam tugas ini ialah menentukan kelas yang hendak dibuat dan cara membahagikan kerja di antara mereka."

"Semakin mereka menyelesaikan soalan sedemikian, semakin mereka menyedari bahawa beberapa penyelesaian adalah baik, manakala yang lain adalah buruk."

"Penyelesaian yang buruk biasanya menimbulkan lebih banyak masalah daripada yang diselesaikan. Penyelesaian yang tidak baik, mewujudkan banyak batasan yang tidak perlu, dsb. Dan penyelesaian yang baik adalah sebaliknya."

"Adakah terdapat analogi yang boleh anda buat?"

"Katakan anda sedang membina sebuah rumah. Dan anda sedang memikirkan apa yang akan dibuat. Anda memutuskan anda memerlukan dinding, lantai dan siling. Akibatnya, anda membina sebuah rumah dengan bumbung rata dan tidak asas. Rumah seperti itu akan retak, dan bumbung akan bocor. Ini adalah penyelesaian yang tidak baik."

"Sebaliknya, rumah yang terdiri daripada asas, dinding, dan bumbung gable akan menjadi penyelesaian yang baik. Salji lebat tidak menimbulkan masalah, kerana salji akan menggelongsor dari bumbung. Dan tanah yang beralih tidak perlu ditakuti, kerana asas akan memastikan kestabilan. Kami akan memanggil penyelesaian sedemikian baik."

"Saya faham. Terima kasih."

"OK. Kalau begitu saya teruskan."

"Pada masanya, penyelesaian yang baik dikenali sebagai corak reka bentuk, manakala yang buruk dipanggil anti-corak."

"Corak reka bentuk adalah seperti jawapan kepada soalan. Sukar untuk difahami jika anda tidak pernah mendengar soalan itu."

" Kategori corak pertama ialah corak ciptaan. Corak sedemikian menerangkan penyelesaian yang baik berkaitan dengan penciptaan objek."

"Apa yang rumit tentang mencipta objek?"

"Apabila ia berlaku, itulah yang akan kita terokai sekarang."

Corak singleton.

Corak reka bentuk: tunggal, kilang, kaedah kilang, kilang abstrak - 1

"Selalunya dalam program, hanya satu salinan beberapa objek boleh wujud. Contohnya, konsol, pembalak, pemungut sampah, dll."

" Penyelesaian buruk: jangan buat sebarang objek — cuma buat kelas yang kaedahnya semuanya statik."

" Penyelesaian yang baik:  cipta satu objek dan simpannya dalam pembolehubah statik. Halang penciptaan objek kedua kelas. Contohnya:"

Contoh
class Sun
{
 private static Sun instance;
 public static Sun getInstance()
 {
  if (instance == null)
  instance = new Sun();

  return instance;
 }

 private Sun()
 {
 }
}
Bagaimana ia dipanggil
Sun sun = Sun.getInstance();

"Ia mudah."

"Pertama, kami menjadikan pembina peribadi. Sekarang ia hanya boleh dipanggil dari dalam kelas kami. Kami telah menyekat penciptaan objek Sun di mana-mana kecuali dalam kaedah kelas Sun."

"Kedua, objek kelas ini hanya boleh diperolehi dengan memanggil kaedah getInstance(). Bukan sahaja kaedah ini boleh mencipta objek Matahari, ia juga memastikan bahawa terdapat hanya satu objek sedemikian."

"Saya faham."

"Apabila anda berfikir, «Sekarang, bagaimana sebenarnya saya akan melakukannya?», satu corak berkata, «anda boleh mencuba ini — ini adalah salah satu penyelesaian terbaik."

"Terima kasih. Sekarang keadaan mula menjadi jelas."

"Anda juga boleh membaca tentang corak ini  di sini ."

Corak kilang.

Corak reka bentuk: tunggal, kilang, kaedah kilang, kilang abstrak - 2

"Inilah situasi yang sering dihadapi oleh pengaturcara. Anda mempunyai beberapa kelas asas dan banyak subkelas. Contohnya, kelas watak permainan (GamePerson) dan kelas untuk semua watak lain yang mewarisinya."

"Katakan anda mempunyai kelas berikut:"

Contoh
abstract class GamePerson
{
}

class Warrior extends GamePerson
{
}

class Mag extends GamePerson
{
}

class Troll extends GamePerson
{
}

class Elf extends GamePerson
{
}

"Persoalannya ialah bagaimana kita menguruskan penciptaan objek kelas ini dengan fleksibel dan mudah."

"Jika masalah ini nampaknya tidak masuk akal kepada anda, bayangkan bahawa dalam permainan anda perlu mencipta berpuluh-puluh pedang dan perisai, beratus-ratus mantra sihir, dan beribu-ribu raksasa. Anda tidak boleh melakukannya tanpa pendekatan yang mudah untuk mencipta objek di sini. "

" Corak Kilang menawarkan penyelesaian yang baik."

"Pertama, kita perlu mencipta enum yang nilainya sepadan dengan pelbagai kelas."

"Kedua, buat kelas Kilang khas yang mempunyai kaedah statik yang mencipta objek berdasarkan nilai enum."

"Sebagai contoh:"

Contoh
public enum PersonType
{
 UNKNOWN,
 WARRIOR,
 MAG,
 TROLL,
 ELF,
}

public class PersonFactory
{
 public static GamePerson createPerson(PersonType personType)
 {
  switch(personType)
  {
   WARRIOR:
   return new Warrior();
   MAG:
   return new Mag();
   TROLL:
   return new Troll();
   ELF:
   return new Elf();
   default:
   throw new GameException();
  }
 }
}
Bagaimana ia dipanggil
GamePerson person = PersonFactory.createPerson(PersonType.MAG);

"Dengan kata lain, kami mencipta kelas khas untuk menguruskan penciptaan objek?"

"Ya."

"Jadi apakah kelebihan yang diberikan oleh ini?"

"Pertama, dalam kelas ini, objek boleh dimulakan dengan data yang diperlukan."

"Kedua, anda boleh lulus nilai enum yang diperlukan antara kaedah seberapa banyak yang anda suka untuk akhirnya mencipta objek yang dikehendaki."

"Ketiga, bilangan medan enum tidak perlu sepadan dengan bilangan kelas. Mungkin terdapat banyak jenis aksara, tetapi beberapa kelas."

"Sebagai contoh, Mag & Pahlawan mungkin menggunakan satu kelas (Manusia), tetapi dengan kekuatan dan sifat sihir yang berbeza (hujah pembina)."

"Inilah rupanya (untuk kejelasan, saya juga telah menambah bunian gelap):"

Contoh
public enum PersonType
{
 UNKNOWN,
 WARRIOR,
 MAG,
 TROLL,
 ELF,
 DARK_ELF
}

public class PersonFactory
{
 public static GamePerson createPerson(PersonType personType)
 {
  switch(personType)
  {
   WARRIOR:
   return new Human(10, 0); // Strength, magic
   MAG:
   return new Human(0, 10); // Strength, magic
   TROLL:
   OGR:
   return new Troll();
   ELF:
   return new Elf(true); // true – good, false – evil
   DARK_ELF:
   return new Elf(false); // true – good, false – evil
   default:
   throw new GameException();
  }
 }
}
Bagaimana ia dipanggil
GamePerson person = PersonFactory.createPerson(PersonType.MAG);

"Dalam contoh di atas, kami hanya menggunakan tiga kelas untuk mencipta enam jenis objek yang berbeza. Ini sangat mudah. ​​Selain itu, kami mempunyai semua logik ini tertumpu dalam satu kelas dan satu kaedah."

"Sekarang andaikan kami memutuskan untuk mencipta kelas berasingan untuk Ogre - kami hanya menukar beberapa baris kod di sini, dan bukan separuh daripada aplikasi."

"Saya setuju. Itu penyelesaian yang baik."

"Dan itulah yang saya bincangkan: corak reka bentuk ialah koleksi penyelesaian yang baik."

"Saya juga berharap saya tahu di mana untuk menggunakannya…"

"Ya. Saya setuju, anda tidak akan faham serta-merta. Namun, lebih baik tahu dan tidak boleh buat daripada tidak tahu dan tidak boleh buat. Ini satu lagi pautan berguna untuk anda tentang corak ini: Corak Kilang "

"Oh terima kasih."

" Corak kilang abstrak ."

"Kadang-kadang apabila anda mempunyai banyak objek, idea untuk mencipta kilang untuk kilang membayangkan dirinya sendiri. Kilang sedemikian dipanggil kilang abstrak ."

"Di mana ini diperlukan?!"

"Andaikan anda mempunyai beberapa kumpulan objek yang serupa. Ini lebih mudah ditunjukkan dengan contoh."

"Sekarang, katakan anda mempunyai tiga perlumbaan dalam permainan anda: manusia, bunian dan syaitan. Dan untuk keseimbangan, setiap perlumbaan mempunyai pahlawan, pemanah dan ahli sihir. Pemain hanya boleh mencipta objek kepunyaan perlumbaan yang dimainkannya. dalam permainan. Begini rupanya dalam kod:"

Pengisytiharan kelas askar
class Warrior
{
}
class Archer
{
}
class Mag
{
}
Manusia
class HumanWarrior extends Warrior
{
}

class HumanArcher extends Archer
{
}

class HumanMag extends Mag
{
}
Bunian
class ElfWarrior extends Warrior
{
}

class ElfArcher extends Archer
{
}

class ElfMag extends Mag
{
}
syaitan
class DaemonWarrior extends Warrior
{
}

class DaemonArcher extends Archer
{
}

class DaemonMag extends Mag
{
}

Dan sekarang mari kita cipta perlumbaan, atau kita juga boleh memanggil mereka tentera.

Tentera
abstract class Army
{
 public Warrior createWarrior();
 public Archer createArcher();
 public Mag createMag();
}
Tentera manusia
class HumanArmy extends Army
{
 public Warrior createWarrior()
 {
  return new HumanWarrior();
 }
 public Archer createArcher()
 {
  return new HumanArcher();
 }
 public Mag createMag()
 {
  return new HumanMag();
 }
}
tentera bunian
class ElfArmy extends Army
{
 public Warrior createWarrior()
 {
  return new ElfWarrior();
 }
 public Archer createArcher()
 {
  return new ElfArcher();
 }
 public Mag createMag()
 {
  return new ElfMag();
 }
}
tentera syaitan
class DaemonArmy extends Army
{
 public Warrior createWarrior()
 {
  return new DaemonWarrior();
 }
 public Archer createArcher()
 {
  return new DaemonArcher();
 }
 public Mag createMag()
 {
  return new DaemonMag();
 }
}

"Tetapi bagaimana anda menggunakan ini?"

"Anda boleh menggunakan kelas Tentera, Pahlawan, Pemanah dan Mage di mana-mana sahaja dalam program ini, dan untuk mencipta objek yang diperlukan - hanya lulus objek subkelas Tentera yang dikehendaki."

"Sebagai contoh:"

Contoh
Army humans = new HumanArmy();
Army daemons = new DaemonArmy();

Army winner = FightSimulator.simulate(humans, daemons);

"Dalam contoh di atas, kami mempunyai kelas yang mensimulasikan pertempuran antara kaum (tentera) yang berbeza. Anda hanya perlu melepasi dua objek Tentera. Kelas itu sendiri menggunakannya untuk mencipta pelbagai tentera dan menjalankan pertempuran maya antara mereka untuk mengenal pasti pemenang. ."

"Saya faham. Terima kasih. Pendekatan yang sangat menarik."

"Penyelesaian yang baik, tidak kira apa yang anda katakan."

"Ya."

"Berikut adalah satu lagi pautan yang baik mengenai topik:  Corak kilang abstrak "