Tópicos Avançados em Linguagem de Programação Padrões de Projeto Prof. Alexandre Vidal DEINF-UFMA Classificação: Propósito: Criacional Escopo: Objetos Intenção: Construção Intenção: define uma interface para criar um objeto, mas deixa as subclasses decidirem que classes instanciar. a.k.a. virtual constructor Motivação frameworks: considere um arcabouço para aplicações que pode apresentar múltiplos documentos para o usuário o arcabouço define duas classes abstratas: Application e Document o tipo de documento que a aplicação deve abrir depende do tipo de aplicação o arcabouço deve instanciar classes, mas só conhece classes abstratas
Motivação aplicabilidade (use quando): uma classe não pode antecipar a classe de objetos que deve criar; uma classe quer que suas subclasses especifiquem os objetos que criam; quiser localizar o conhecimento a respeito de subclasses às quais são delegadas responsabilidades específicas (em hierarquias de classes paralelas) aplicabilidade (hirarquias de classes paralelas)
Estrutura Participantes Product: define a interface dos objetos criados pelo método fábrica; ConcreteProduct: implementa a interface definida em Product; Creator: declara o método fábrica (que retorna um objeto do tipo Product; ConcreteCreator: redefine o método fábrica para retornar uma instância da classe ConcreteProduct. Colaborações Creator depende de suas subclasses para definir o método fábrica que retorne uma instância do ConcretProduct apropriado
Conseqüências o código lida somente com a interface de Product é mais vantajoso quando Creator precisa ter subclasses de qualquer maneira conecta hierarquia de classes paralelas que ocorrem quando uma classe delega algumas de suas responsabilidades para uma classe separada Implementação (alternativas) Creator é uma classe abstrata e não fornece implementação para o método fábrica; Creator é uma classe concreta e fornece implementação por omissão (default) para o método fábrica; métodos fábrica parametrizados; templates para evitar o uso de subclasses. Exemplo de código class MazeGame { Maze* CreateMaze(); // builds and returns a maze // factory methods: virtual Maze* MakeMaze() const { return new Maze; } virtual Room* MakeRoom(int n) const { return new Room(n); } virtual Wall* MakeWall() const { return new Wall; } virtual Door* MakeDoor(Room* r1, Room* r2) const { return new Door(r1, r2); } };
Maze* MazeGame::CreateMaze () { // implementando CreateMaze Maze* amaze = MakeMaze(); Room* r1 = MakeRoom(1); Room* r2 = MakeRoom(2); Door* thedoor = MakeDoor(r1, r2); amaze->addroom(r1); amaze->addroom(r2); r1->setside(north, MakeWall()); r1->setside(east, thedoor); r1->setside(south, MakeWall()); r1->setside(west, MakeWall()); r2->setside(north, MakeWall());... return amaze; } class BombedMazeGame : public MazeGame { BombedMazeGame(); virtual Wall* MakeWall() const { return new BombedWall; } virtual Room* MakeRoom(int n) const { return new RoomWithABomb(n); } }; // An EnchantedMazeGame variant... class EnchantedMazeGame : public MazeGame { EnchantedMazeGame(); virtual Room* MakeRoom(int n) const { return new EnchantedRoom(n, CastSpell()); } virtual Door* MakeDoor(Room* r1, Room* r2) const { return new DoorNeedingSpell(r1,r2); } protected: Spell* CastSpell() const; }; Usos conhecidos ver página 120 no GoF (traduzido); Padrões Relacionados Abstract Factory pode ser implementado usando o Template Method costuma chamar s Prototype introduz um método Initialize na classe Creator do