– Szia Amigo!

– Szia, Bilaabo!

"A mai témánk nemcsak érdekes lesz, hanem egyenesen epikus."

"Ma elmondom neked, mik azok a tervezési minták. "

"Csodálatos! Sokat hallottam róluk. Alig várom!"

"A tapasztalt programozóknak sok osztályt kell írniuk. De ennek a munkának a legnehezebb része annak eldöntése, hogy mely osztályokat hozzanak létre, és hogyan osszák fel közöttük a munkát."

"Minél többet oldottak meg ilyen kérdéseket, annál inkább rájöttek, hogy egyes megoldások jók, míg mások rosszak."

"A rossz megoldások általában több problémát okoznak, mint amennyit megoldanak. Rosszul terjednek ki, sok szükségtelen korlátot hoznak létre stb. A jó megoldások pedig az ellenkezője."

– Tudsz valami hasonlatot mondani?

"Tegyük fel, hogy házat építesz. És azon gondolkozol, hogy miből lesz. Úgy döntesz, hogy falakra, padlóra és mennyezetre van szükséged. Ennek eredményeként olyan házat építesz, amelynek lapos teteje van, és nem Egy ilyen ház megreped, és a tető szivárog. Ez egy rossz megoldás."

"Megfordítva, egy alapból, falakból és nyeregtetőből álló ház jó megoldás lenne. Az erős havazás nem okoz gondot, mert a hó lecsúszik a tetőről. A talaj eltolódásától pedig nem kell tartani, mert az alap gondoskodik egy ilyen megoldást jónak neveznénk."

– Értem. Köszönöm.

"Rendben. Akkor folytatom."

"Idővel a jó megoldásokat tervezési mintáknak, míg a rosszakat anti-mintának nevezték."

"A tervezési minta olyan, mint egy kérdésre adott válasz. Nehéz megérteni, ha még soha nem hallottad a kérdést."

" A minták első kategóriája az alkotási minták. Az ilyen minták a tárgyak létrehozásával kapcsolatos jó megoldásokat írják le."

– Mi olyan bonyolult az objektumok létrehozásában?

"Ahogy megtörténik, most éppen ezt fogjuk megvizsgálni."

Singleton minta.

Tervezési minták: singleton, gyári, gyári módszer, absztrakt gyár - 1

"A programokban gyakran csak egy példány létezhet egyes objektumokból. Például a konzol, a naplózó, a szemétgyűjtő stb."

" Rossz megoldás: ne hozzon létre objektumokat – csak hozzon létre egy osztályt, amelynek metódusai mind statikusak."

" Jó megoldás:  hozzon létre egyetlen objektumot, és tárolja egy statikus változóban. Akadályozza meg az osztály második objektumának létrehozását. Például:"

Példa
class Sun
{
 private static Sun instance;
 public static Sun getInstance()
 {
  if (instance == null)
  instance = new Sun();

  return instance;
 }

 private Sun()
 {
 }
}
Hogy hívják
Sun sun = Sun.getInstance();

"Ez egyszerű."

"Először is priváttá tesszük a konstruktort. Most már csak az osztályunkon belülről hívható meg. Mindenhol letiltottuk a Sun objektumok létrehozását, kivéve a Sun osztály metódusaiban."

"Másodszor, ennek az osztálynak az objektuma csak a getInstance() metódus meghívásával érhető el. Nemcsak ez az egyetlen metódus, amely képes Sun objektumot létrehozni, hanem azt is biztosítja, hogy csak egy ilyen objektum legyen."

"Látom."

"Amikor arra gondolsz, hogy "Most pontosan hogyan csinálnám?", egy minta azt mondja: "Ezt kipróbálhatod - ez az egyik legjobb megoldás."

"Köszönöm. Most kezdenek világosodni a dolgok."

"Erről a mintáról itt is olvashatsz  ."

Gyári minta.

Tervezési minták: singleton, gyári, gyári módszer, absztrakt gyár - 2

"Itt van egy olyan helyzet, amellyel a programozók nagyon gyakran szembesülnek. Van néhány alaposztálya és sok alosztálya. Például egy játékkarakterosztály (GamePerson) és osztályok az összes többi karakterhez, amelyek öröklik."

"Tegyük fel, hogy a következő osztályai vannak:

Példa
abstract class GamePerson
{
}

class Warrior extends GamePerson
{
}

class Mag extends GamePerson
{
}

class Troll extends GamePerson
{
}

class Elf extends GamePerson
{
}

"A kérdés az, hogy hogyan tudjuk rugalmasan és kényelmesen kezelni ezen osztályok objektumainak létrehozását."

"Ha ez a probléma távolinak tűnik számodra, képzeld el, hogy a játékban tucatnyi kardot és pajzsot, varázslatok százait és szörnyek ezreit kell létrehoznod. Itt nem nélkülözheted a tárgyak létrehozásának kényelmes megközelítését. "

– A Gyári minta jó megoldást kínál.

"Először is létre kell hoznunk egy enumot, amelynek értékei megfelelnek a különböző osztályoknak."

"Másodszor hozzon létre egy speciális Factory osztályt, amelynek statikus metódusai vannak, amelyek egy enum érték alapján hoznak létre objektumot."

"Például:"

Példa
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();
  }
 }
}
Hogy hívják
GamePerson person = PersonFactory.createPerson(PersonType.MAG);

"Más szóval, létrehoztunk egy speciális osztályt az objektumok létrehozásának kezelésére?"

"Igen."

– Szóval milyen előnyökkel jár ez?

"Először is, ebben az osztályban az objektumok inicializálhatók a szükséges adatokkal."

"Másodszor, a kívánt enum értéket bármennyire átadhatja a metódusok között, hogy végül létrehozza a kívánt objektumot."

"Harmadszor, az enum mezők számának nem kell egyeznie az osztályok számával. Lehet sokféle karakter, de kevés osztály."

"Például egy Mag & Warrior használhat egy osztályt (Human), de eltérő erősséggel és mágikus tulajdonságokkal (konstruktori argumentumok)."

"Íme, hogyan nézhet ki (az egyértelműség kedvéért sötételfeket is hozzáadtam):"

Példa
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();
  }
 }
}
Hogy hívják
GamePerson person = PersonFactory.createPerson(PersonType.MAG);

"A fenti példában mindössze három osztályt használtunk hat különböző típusú objektum létrehozására. Ez nagyon kényelmes. Ráadásul mindezt a logikát egy osztályban és egy metódusban koncentráltuk."

"Most tegyük fel, hogy úgy döntünk, hogy külön osztályt hozunk létre az Ogre számára – egyszerűen csak néhány sort módosítunk itt, és nem az alkalmazás felét."

– Egyetértek. Ez jó megoldás.

"És erről beszélek: a tervezési minták jó megoldások gyűjteményei."

– Azt is szeretném, ha tudnám, hol kell használni…

"Igen. Egyetértek, nem fogod azonnal megérteni. Mégis, jobb tudni és nem tudni, mint nem tudni és nem tudni. Itt van egy másik hasznos link az Ön számára erről a mintáról: Gyári minta "

"Ó, köszönöm."

" Absztrakt gyári minta."

"Néha, amikor sok tárgy van, felvetődik az ötlet, hogy gyárat hozzunk létre a gyárak számára. Az ilyen gyárat absztrakt gyárnak hívják ."

– Hol lenne erre szükség?

"Tegyük fel, hogy több azonos objektumcsoportja van. Ezt egyszerűbb példával bemutatni."

"Most tegyük fel, hogy három faj van a játékban: emberek, elfek és démonok. És az egyensúly érdekében minden fajnak vannak harcosai, íjászok és mágusai. A játékos csak ahhoz a fajhoz tartozó tárgyakat hozhat létre, amelyekért játszik. a játékban. Így nézne ki a kódban:"

Nyilatkozat a katonaosztályokról
class Warrior
{
}
class Archer
{
}
class Mag
{
}
Emberek
class HumanWarrior extends Warrior
{
}

class HumanArcher extends Archer
{
}

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

class ElfArcher extends Archer
{
}

class ElfMag extends Mag
{
}
Démonok
class DaemonWarrior extends Warrior
{
}

class DaemonArcher extends Archer
{
}

class DaemonMag extends Mag
{
}

És most hozzuk létre a fajokat, vagy nevezhetjük seregeknek is.

Hadseregek
abstract class Army
{
 public Warrior createWarrior();
 public Archer createArcher();
 public Mag createMag();
}
Emberi hadsereg
class HumanArmy extends Army
{
 public Warrior createWarrior()
 {
  return new HumanWarrior();
 }
 public Archer createArcher()
 {
  return new HumanArcher();
 }
 public Mag createMag()
 {
  return new HumanMag();
 }
}
Elf hadsereg
class ElfArmy extends Army
{
 public Warrior createWarrior()
 {
  return new ElfWarrior();
 }
 public Archer createArcher()
 {
  return new ElfArcher();
 }
 public Mag createMag()
 {
  return new ElfMag();
 }
}
Démon hadsereg
class DaemonArmy extends Army
{
 public Warrior createWarrior()
 {
  return new DaemonWarrior();
 }
 public Archer createArcher()
 {
  return new DaemonArcher();
 }
 public Mag createMag()
 {
  return new DaemonMag();
 }
}

– De hogyan használod ezt?

"Az Army, Warrior, Archer és Mage osztályokat bárhol használhatja a programban, és létrehozhatja a szükséges objektumokat - egyszerűen adja át a kívánt Army alosztály objektumát."

"Például:"

Példa
Army humans = new HumanArmy();
Army daemons = new DaemonArmy();

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

"A fenti példában van egy osztályunk, amely a különböző fajok (seregek) közötti csatákat szimulálja. Csak el kell múlnia a hadsereg két objektumán. Az osztály maga használja őket különböző csapatok létrehozására, és virtuális csatákat folytat közöttük a győztes azonosítása érdekében ."

"Értem. Köszönöm. Nagyon érdekes megközelítés."

– Jó megoldás, függetlenül attól, hogy mit mondasz.

"Igen."

"Itt van még egy jó link a témában:  Absztrakt gyári minta "