| A gyártófüggvény (Factory Method) |
|
|
|
| Hírek - Programozás, tervezés | |||
| Írta: Carlos | |||
A gyártófüggvény egy létrehozási minta, amely mentesíti a kliens oldalt a létrehozandó objektumok típusának ismeretétől, és az azzal járó többletlogika implementálásától. A gyártófüggvény bevetése a következő feltételek esetén megfontolandó:- kliens (azaz hívó) oldalon egy öröklődési hierarchiában szerepelő osztályok példányosítását végezzük el (a new hívások nagy sűrűsége árulkodó jel lehet) - kiaknázzuk a többalakúságban rejlő lehetőségeket (az adott osztályok rendelkeznek virtuális függvényekkel) A többalakúság (polimorfizmus) elegáns megoldásoat tesz lehetővé. Az ősosztály pointerén keresztül hivatkozunk egy tagfüggvényre, és futásidőben a rendszer beazonosítja a megfelelő példányt, és a megfelelő osztály virtuális függvénye kerül meghívásra. A típust a kód írásakor csak egy kivételes esetben kell megadnunk - éspedig a példányosításkor (létrehozáskor a megfelelő típus konstruktorát kell meghívnunk). Az alábbi kódrészlet ezt a megvalósítást mutatja be: // ősosztály class BaseMesh { public: virtual void render() = 0; }; class SolidMesh : public BaseMesh { public: void render() { cout << "SolidMesh: rendering...\n"; } }; class WireframeMesh : public BaseMesh { public: void render() { cout << "WireframeMesh: rendering...\n"; } }; class TexturedMesh : public BaseMesh { public: void render() { cout << "TexturedMesh: rendering...\n"; } }; int main( void ) { // lista a megjelenítendő objektum-poinetrek nyilvántartására vector renderQueue; int meshType; // feltöltjük a megjelenítendő objektumok listáját while (true) { cout << "SolidMesh(1) WireframeMesh(2) TexturedMesh(3) Go(0): "; cin >> meshType; if (meshType == 0) { break; } else if (meshType == 1) { renderQueue.push_back( new SolidMesh ); } else if (meshType == 2) { renderQueue.push_back( new WireframeMesh ); } // default ág else { renderQueue.push_back( new TexturedMesh ); } } // meghívjuk az objektumok render függvényét for ( int i = 0; i < renderQueue.size(); ++i ) { renderQueue[i]->render(); } // nagytakarítás for ( int i = 0; i < renderQueue.size(); ++i ) { delete renderQueue[i]; } } Ez a megvalósítás kikényszeríti, hogy a kliens ismerje a példányosítandó típusokat. Magyarán a main függvényben minden egyes típust ismernünk kell ahhoz, hogy a new operátor segítségével példányosítsuk őket.) Emiatt minden új típus megjelenésekor bővítenünk kell a hívó oldal kódját; ha például bevezetünk egy MultitexturedMesh típust, akkor egy új "else if" ágban kell lekezelnünk a létrehozását. A kliens tehermentesíthető a típusok ismeretétől, a megoldást pedig a gyártófüggvény jelenti. A gyártófüggvénynek természetesen ismernie kell az új típust, mivel a létrehozása itt történik meg. A következő kódsorok a gyártófüggvény egy lehetséges megvalósítását mutatja be; a makeMesh() gyártófüggvényt egy statikus tagfüggvényként definiáljuk a BaseMesh ősosztályban: class BaseMesh { public: // Factory Method static BaseMesh* makeMesh( int choice ); virtual void render() = 0; }; // a gyártófüggvény implementációja BaseMesh* BaseMesh::makeMesh( int meshType ) { BaseMesh* meshPtr = null; if ( meshType == 1 ) { meshPtr = new SolidMesh(); } else if ( meshType == 2 ) { meshPtr = new WireframeMesh(); } else { meshPtr = TexturedMesh(); } return meshPtr; } int main( void ) { vector renderQueue; int meshType; // feltöltjük a megjelenítendő objektumok listáját // a lényeges különbség az előző verzióhoz képest az, // hogy nem jelennek meg a származtatott BaseMesh típusok (SolidMesh, WireframeMesh, illetve TexturedMesh) // és a new operátor sem szerepel - helyette a BaseMesh::makeMesh( meshType ) fv.-t hívjuk meg while (true) { cout << "SolidMesh(1) WireframeMesh(2) TexturedMesh(3) Go(0): "; cin >> meshType; if (meshType == 0) { break; } renderQueue.push_back( BaseMesh::makeMesh( meshType ) ); } // meghívjuk az objektumok render függvényét for ( int i = 0; i < renderQueue.size(); ++i ) { renderQueue[i]->render(); } // nagytakarítás for ( int i = 0; i < renderQueue.size(); ++i ) { delete renderQueue[i]; } } class SolidMesh : public BaseMesh { public: void render() { cout << "SolidMesh: rendering...\n"; } }; class WireframeMesh : public BaseMesh { public: void render() { cout << "WireframeMesh: rendering...\n"; } }; class TexturedMesh : public BaseMesh { public: void render() { cout << "TexturedMesh: rendering...\n"; } }; Sikerélményekben gazdag kódírást! Nyisztor Károly http://www.nyisztorkaroly.org
|
Legfrisebb fórumbejegyzések
- Vá: Szakmai kérdések
Quantum 2.9.2010 18:12 - Vá: Szakmai kérdések
admin 2.9.2010 18:00 - Vá: Szakmai kérdések
Quantum 2.9.2010 12:58 - Vá: Szakmai kérdések
Quantum 27.8.2010 15:01 - Vá: Szakmai kérdések
admin 19.8.2010 22:53
Támogatja a Joomla!. Designed by: Joomla Theme, linux hosting. Valid XHTML and CSS.



A gyártófüggvény bevetése a következő feltételek esetén megfontolandó: