Декоратор (шаблон проектирования)
- 1 year ago
- 0
- 0
Абстрактная фабрика ( англ. Abstract factory ) — порождающий шаблон проектирования , предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не специфицируя их конкретных классов. Шаблон реализуется созданием абстрактного класса Factory, который представляет собой интерфейс для создания компонентов системы (например, для оконного интерфейса он может создавать окна и кнопки). Затем пишутся классы , реализующие этот интерфейс .
Предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не специфицируя их конкретных классов.
//: Playground - noun: a place where people can play
/// <summary>
/// Класс абстрактной фабрики
/// </summary>
protocol AbstractFactory {
func createProductA() -> AbstractProductA
func createProductB() -> AbstractProductB
}
/// <summary>
/// Класс фабрики № 1
/// </summary>
class ConcreteFactory1: AbstractFactory {
public func createProductA() -> AbstractProductA {
return ProductA1()
}
public func createProductB() -> AbstractProductB {
return ProductB1()
}
}
/// <summary>
/// Класс фабрики № 2
/// </summary>
class ConcreteFactory2 : AbstractFactory {
public func createProductA() -> AbstractProductA {
return ProductA2()
}
public func createProductB() -> AbstractProductB {
return ProductB2()
}
}
/// <summary>
/// Абстрактный класс продукта А
/// </summary>
protocol AbstractProductA {}
//
/// <summary>
/// Абстрактный класс продукта В
/// </summary>
protocol AbstractProductB {
func interact(a: AbstractProductA)
}
/// <summary>
/// Первый класс продукта типа А
/// </summary>
class ProductA1 : AbstractProductA {}
/// <summary>
/// Первый класс продукта типа В
/// </summary>
class ProductB1 : AbstractProductB {
public func interact(a: AbstractProductA) {
print("\(type(of:self)) interacts with \(type(of: a.self))")
}
}
/// <summary>
/// Второй класс продукта типа А
/// </summary>
class ProductA2 : AbstractProductA {}
/// <summary>
/// Второй класс продукта типа В
/// </summary>
class ProductB2 : AbstractProductB {
public func interact(a: AbstractProductA) {
print("\(type(of:self)) interacts with \(type(of: a.self))")
}
}
/// <summary>
/// Класс клиента, в котором происходит взаимодействие между объектами
/// </summary>
class Client {
private let _abstractProductA: AbstractProductA
private let _abstractProductB: AbstractProductB
// Конструктор
public init(factory: AbstractFactory) {
_abstractProductB = factory.createProductB();
_abstractProductA = factory.createProductA();
}
public func run() {
_abstractProductB.interact(a: _abstractProductA)
}
}
/// <summary>
/// Точка входа в приложение
/// </summary>
// Вызов абстрактной фабрики № 1
let factory1 = ConcreteFactory1()
let client1 = Client(factory: factory1)
client1.run()
// Вызов абстрактной фабрики № 2
let factory2 = ConcreteFactory2()
let client2 = Client(factory: factory2)
client2.run()
using System;
namespace DoFactory.GangOfFour.Abstract.Structural
{
class MainApp
{
/// <summary>
/// Точка входа в приложение
/// </summary>
public static void Main()
{
// Вызов абстрактной фабрики № 1
AbstractFactory factory1 = new ConcreteFactory1();
Client client1 = new Client(factory1);
client1.Run();
// Вызов абстрактной фабрики № 2
AbstractFactory factory2 = new ConcreteFactory2();
Client client2 = new Client(factory2);
client2.Run();
// Ожидание ввода
Console.ReadKey();
}
}
/// <summary>
/// Класс абстрактной фабрики
/// </summary>
abstract class AbstractFactory
{
public abstract AbstractProductA CreateProductA();
public abstract AbstractProductB CreateProductB();
}
/// <summary>
/// Класс фабрики № 1
/// </summary>
class ConcreteFactory1 : AbstractFactory
{
public override AbstractProductA CreateProductA()
{
return new ProductA1();
}
public override AbstractProductB CreateProductB()
{
return new ProductB1();
}
}
/// <summary>
/// Класс фабрики № 2
/// </summary>
class ConcreteFactory2 : AbstractFactory
{
public override AbstractProductA CreateProductA()
{
return new ProductA2();
}
public override AbstractProductB CreateProductB()
{
return new ProductB2();
}
}
/// <summary>
/// Абстрактный класс продукта А
/// </summary>
abstract class AbstractProductA
{
}
/// <summary>
/// Абстрактный класс продукта В
/// </summary>
abstract class AbstractProductB
{
public abstract void Interact(AbstractProductA a);
}
/// <summary>
/// Первый класс продукта типа А
/// </summary>
class ProductA1 : AbstractProductA
{
}
/// <summary>
/// Первый класс продукта типа В
/// </summary>
class ProductB1 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
Console.WriteLine(this.GetType().Name +
" interacts with " + a.GetType().Name);
}
}
/// <summary>
/// Второй класс продукта типа А
/// </summary>
class ProductA2 : AbstractProductA
{
}
/// <summary>
/// Второй класс продукта типа В
/// </summary>
class ProductB2 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
Console.WriteLine(this.GetType().Name +
" interacts with " + a.GetType().Name);
}
}
/// <summary>
/// Класс клиента, в котором происходит взаимодействие между объектами
/// </summary>
class Client
{
private AbstractProductA _abstractProductA;
private AbstractProductB _abstractProductB;
// Конструктор
public Client(AbstractFactory factory)
{
_abstractProductB = factory.CreateProductB();
_abstractProductA = factory.CreateProductA();
}
public void Run()
{
_abstractProductB.Interact(_abstractProductA);
}
}
}
public class AbstractFactoryExample {
public static void main(String[] args) {
AbstractFactory factory1 = new ConcreteFactory1();
Client client1 = new Client(factory1);
client1.execute();
AbstractFactory factory2 = new ConcreteFactory2();
Client client2 = new Client(factory2);
client2.execute();
}
}
class Client {
private AbstractProductA productA;
private AbstractProductB productB;
Client(AbstractFactory factory) {
productA = factory.createProductA();
productB = factory.createProductB();
}
void execute() {
productB.interact(productA);
}
}
interface AbstractFactory {
AbstractProductA createProductA();
AbstractProductB createProductB();
}
interface AbstractProductA {
void interact(AbstractProductB b);
}
interface AbstractProductB {
void interact(AbstractProductA a);
}
class ConcreteFactory1 implements AbstractFactory {
@Override
public AbstractProductA createProductA() {
return new ProductA1();
}
@Override
public AbstractProductB createProductB() {
return new ProductB1();
}
}
class ConcreteFactory2 implements AbstractFactory {
@Override
public AbstractProductA createProductA() {
return new ProductA2();
}
@Override
public AbstractProductB createProductB() {
return new ProductB2();
}
}
class ProductA1 implements AbstractProductA {
@Override
public void interact(AbstractProductB b) {
System.out.println(this.getClass().getName() + " interacts with " + b.getClass().getName());
}
}
class ProductB1 implements AbstractProductB {
@Override
public void interact(AbstractProductA a) {
System.out.println(this.getClass().getName() + " interacts with " + a.getClass().getName());
}
}
class ProductA2 implements AbstractProductA {
@Override
public void interact(AbstractProductB b) {
System.out.println(this.getClass().getName() + " interacts with " + b.getClass().getName());
}
}
class ProductB2 implements AbstractProductB {
@Override
public void interact(AbstractProductA a) {
System.out.println(this.getClass().getName() + " interacts with " + a.getClass().getName());
}
}
interface IHead
{
public function drawHead($x, $y);
}
class RedHead implements IHead
{
public function drawHead($x, $y) {
echo 'Your red head in axis x = ' . $x . ' and axis y = ' . $y . '</ br>' . PHP_EOL;
}
}
class WhiteHead implements IHead
{
public function drawHead($x, $y) {
echo 'Your white head in axis x = ' . $x . ' and axis y = ' . $y . '</ br>' . PHP_EOL;
}
}
interface IBody
{
public function drawBody($x, $y);
}
class RedBody implements IBody
{
public function drawBody($x, $y) {
echo 'Your red body in axis x = ' . $x . ' and axis y = ' . $y . '</ br>' . PHP_EOL;
}
}
class WhiteBody implements IBody
{
public function drawBody($x, $y) {
echo 'Your white body in axis x = ' . $x . ' and axis y = ' . $y . '</ br>' . PHP_EOL;
}
}
/**
* Interface ISnowman - this is abstract factory
*/
interface ISnowman
{
public function drawHead($x, $y);
public function drawBody($x, $y);
}
/**
* Class WhiteSnowman - concrete factory
*/
class WhiteSnowman implements ISnowman
{
protected $head;
protected $body;
public function __construct() {
$this->head = new WhiteHead();
$this->body = new WhiteBody();
}
public function drawHead($x, $y) {
$this->head->drawHead($x, $y);
}
public function drawBody($x, $y) {
$this->body->drawBody($x, $y);
}
}
/**
* Class RedSnowman - concrete factory
*/
class RedSnowman implements ISnowman
{
protected $head;
protected $body;
public function __construct() {
$this->head = new RedHead();
$this->body = new RedBody();
}
public function drawHead($x, $y) {
$this->head->drawHead($x, $y);
}
public function drawBody($x, $y) {
$this->body->drawBody($x, $y);
}
}
function snowman(ISnowman $snowman) {
$snowman->drawHead(1,1);
$snowman->drawBody(1,2);
}
$typeSnowman = 'red';
// мы выбираем тип семейства в начале кода
if($typeSnowman == 'red')
$snowman = new RedSnowman();
else
$snowman = new WhiteSnowman();
snowman($snowman);
from abc import ABCMeta, abstractmethod
class Beer(metaclass=ABCMeta):
pass
class Snack(metaclass=ABCMeta):
@abstractmethod
def interact(self, beer: Beer) -> None:
pass
class AbstractShop(metaclass=ABCMeta):
@abstractmethod
def buy_beer(self) -> Beer:
pass
@abstractmethod
def buy_snack(self) -> Snack:
pass
class Tuborg(Beer):
pass
class Staropramen(Beer):
pass
class Peanuts(Snack):
def interact(self, beer: Beer) -> None:
print('Мы выпили по бутылке пива {} и закусили его арахисом'.format(
beer.__class__.__name__))
class Chips(Snack):
def interact(self, beer: Beer) -> None:
print('Мы выпили несколько банок пива {} и съели пачку чипсов'.format(
beer.__class__.__name__))
class ExpensiveShop(AbstractShop):
def buy_beer(self) -> Beer:
return Tuborg()
def buy_snack(self) -> Snack:
return Peanuts()
class CheapShop(AbstractShop):
def buy_beer(self) -> Beer:
return Staropramen()
def buy_snack(self) -> Snack:
return Chips()
if __name__ == '__main__':
expensive_shop = ExpensiveShop()
cheap_shop = CheapShop()
print('OUTPUT:')
beer = expensive_shop.buy_beer()
snack = cheap_shop.buy_snack()
snack.interact(beer)
beer = cheap_shop.buy_beer()
snack = expensive_shop.buy_snack()
snack.interact(beer)
'''
OUTPUT:
Мы выпили несколько банок пива Tuborg и съели пачку чипсов
Мы выпили по бутылке пива Staropramen и закусили его арахисом
'''
abstract class AbstractTerrestrialAnimal {
def walk: String
}
abstract class AbstractWaterAnimal {
def swim: String
}
abstract class AbstractZoo {
def getCity: String
def getTerrestrialAnimal: AbstractTerrestrialAnimal
def getWaterAnimal: AbstractWaterAnimal
}
class Wolverine extends AbstractTerrestrialAnimal {
override def walk: String = "Wolverine is walking"
}
class HoneyBadger extends AbstractTerrestrialAnimal {
override def walk: String = "Honey badger is walking"
}
class Walrus extends AbstractWaterAnimal {
override def swim: String = "Walrus is swimming"
}
class SeaLion extends AbstractWaterAnimal {
override def swim: String = "Sea lion is swimming"
}
class MunichZoo extends AbstractZoo {
override def getCity: String = "Munich"
override def getTerrestrialAnimal: AbstractTerrestrialAnimal = new Wolverine
override def getWaterAnimal: AbstractWaterAnimal = new Walrus
}
class CapeTownZoo extends AbstractZoo {
override def getCity: String = "CapeTown"
override def getTerrestrialAnimal: AbstractTerrestrialAnimal = new HoneyBadger
override def getWaterAnimal: AbstractWaterAnimal = new SeaLion
}
object AbstractFactoryTest {
private def testZoo(zoo: AbstractZoo): Unit = {
println(s"Zoo of ${zoo.getCity}:")
println(zoo.getTerrestrialAnimal.walk)
println(zoo.getWaterAnimal.swim)
}
def main(args: Array[String]) Unit = {
testZoo(new CapeTownZoo)
testZoo(new MunichZoo)
}
}
package main
import "fmt"
type Unit interface {
What() string
}
type Action interface {
What() string
}
type Place interface {
What() string
}
type TransportFactory interface {
MakeUnit() Unit
MakeAction() Action
MakePlace() Place
}
type Car struct{}
func (self Car) What() string {
return "car"
}
type Ride struct{}
func (self Ride) What() string {
return "ride"
}
type Road struct{}
func (self Road) What() string {
return "road"
}
type LandTransportFactory struct{}
func (self LandTransportFactory) MakeUnit() Unit {
return &Car{}
}
func (self LandTransportFactory) MakeAction() Action {
return &Ride{}
}
func (self LandTransportFactory) MakePlace() Place {
return &Road{}
}
type Boat struct{}
func (self Boat) What() string {
return "boat"
}
type Sail struct{}
func (self Sail) What() string {
return "sail"
}
type Sea struct{}
func (self Sea) What() string {
return "sea"
}
type SeaTransportFactory struct{}
func (self SeaTransportFactory) MakeUnit() Unit {
return &Boat{}
}
func (self SeaTransportFactory) MakeAction() Action {
return &Sail{}
}
func (self SeaTransportFactory) MakePlace() Place {
return &Sea{}
}
func action(factory TransportFactory) {
unit := factory.MakeUnit()
unit_action := factory.MakeAction()
place := factory.MakePlace()
fmt.Printf("The %s %ss over the %s.\n",
unit.What(), unit_action.What(), place.What())
}
func main() {
action(&LandTransportFactory{})
action(&SeaTransportFactory{})
}
Вывод
The car rides over the road. The boat sails over the sea.
module AbstractFactoryPattern
# Provide an interface for creating families of related or dependent objects without specifying their concrete classes
# Abstract Factory
class WarriorFactory
def create_knight
raise NotImplementedError
end
def create_archer
raise NotImplementedError
end
end
# Concrete Factory
class OrcWarriorFactory < WarriorFactory
def create_knight
OrcKnight.new
end
def create_archer
OrcArcher.new
end
end
# Concrete Factory
class ElfWarriorFactory < WarriorFactory
def create_knight
ElfKnight.new
end
def create_archer
ElfArcher.new
end
end
# Abstract Product
class Knight
def inspect
self.class.name.split('::').last
end
end
# Abstract Product
class Archer
def inspect
self.class.name.split('::').last
end
end
# Product
class OrcKnight < Knight
end
# Product
class ElfKnight < Knight
end
# Product
class OrcArcher < Archer
end
# Product
class ElfArcher < Archer
end
# Client
class Army
def initialize(factory)
@knights = []
3.times { @knights << factory.create_knight }
@archers = []
3.times { @archers << factory.create_archer }
end
def inspect
"Knights #{@knights.map(&:inspect)} Archers #{@archers.map(&:inspect)}"
end
end
def self.run
orcs = Army.new(OrcWarriorFactory.new)
puts "Orcs army: #{orcs.inspect}"
elves = Army.new(ElfWarriorFactory.new)
puts "Elves army: #{elves.inspect}"
end
end
AbstractFactoryPattern.run
# Orcs army: Knights ["OrcKnight", "OrcKnight", "OrcKnight"] Archers ["OrcArcher", "OrcArcher", "OrcArcher"]
# Elves army: Knights ["ElfKnight", "ElfKnight", "ElfKnight"] Archers ["ElfArcher", "ElfArcher", "ElfArcher"]