Форум сайта python.su
0
В интернетах и в учебниках при объяснении работы паттерна “фабричный метод” используется приблизительно такой пример. его особенность в том, что класс-наследник переопределяет метод родителя, отвечающий за создание объектов(отсюда и название паттерна):
class Door: def __init__(self, weight): self.weight = weight def __str__(self): return str(self.weight) class Brick: def __init__(self, weight): self.weight = weight def __str__(self): return str(self.weight) class FactoryMethod: def create(self, weight, type_): pass class Creator(FactoryMethod): def create(self, type_, weight): if type_ == 'door': print('door with weight: ', Door(weight)) else: print('brick with weight: ', Brick(weight)) c = Creator() c.create('brick', 10) c.create('door', 100)
class Door: def __init__(self, weight): self.weight = weight def __str__(self): return str(self.weight) class Brick: def __init__(self, weight): self.weight = weight def __str__(self): return str(self.weight) class Creator: def create(self, type_, weight): if type_ == 'door': print('door with weight: ', Door(weight)) else: print('brick with weight: ', Brick(weight)) c = Creator() c.create('brick', 10) c.create('door', 100)
Офлайн
568
zlodiak
В очередной раз мы возвращаемся к особенностям питона. Понимаете, многие (да почти все) паттерны актуальны только для статически типизированных языков, для С++, Java, С# и пр. Если вы пишите на Java, вы должны указать компилятору какие атрибуты каких типов содержит объект. FactoryMethod нужен для того, чтобы иметь родительский для всех реализаций тип, чтобы не привязывать код к конкретным реализациям.
так плохо
class Foo: def __init__(self, creator: ConsoleLoggerCreator): self.creator = creator class Bar: def __init__(self, creator: FileLoggerCreator): self.creator = creator
class ConsoleLoggerCreator(LoggerCreatorInteface): ... class FileLoggerCreator(LoggerCreatorInteface): ... class Foo: def __init__(self, creator: LoggerCreatorInteface): self.creator = creator class Bar: def __init__(self, creator: LoggerCreatorInteface): self.creator = creator
Офлайн
857
Проходил по “банде четырёх” и другим разрозненным источникам шаблон фабричный метод.
Вообще, сначала писал на Java пример, так как там есть все синтаксические конструкции для ООП, а потом переводил на Python, Go, JavaScript.
Фабричный метод без параметра
#!/usr/bin/env python3 from abc import ABCMeta, abstractmethod class UnitInterface(metaclass=ABCMeta): @abstractmethod def what(self): pass class Creator(metaclass=ABCMeta): @abstractmethod def make_unit(self): pass def new_unit(self): return self.make_unit() class Dog(UnitInterface): def what(self): return 'dog' class DogCreator(Creator): def make_unit(self): return Dog() class Cat(UnitInterface): def what(self): return 'cat' class CatCreator(Creator): def make_unit(self): return Cat() def action(creator): unit = creator.new_unit() print('The {} is created.'.format(unit.what())) def main(): action(DogCreator()) action(CatCreator()) if __name__ == '__main__': main()
#!/usr/bin/env python3 from abc import ABCMeta, abstractmethod import enum class UnitInterface(metaclass=ABCMeta): @abstractmethod def what(self): pass class Dog(UnitInterface): def what(self): return 'dog' class Cat(UnitInterface): def what(self): return 'cat' class UnitTypes(enum.Enum): DOG = 0 CAT = 1 class Creator: def make_unit(self, unit_type): if unit_type == UnitTypes.DOG: return Dog() elif unit_type == UnitTypes.CAT: return Cat() else: raise ValueError("unit type is unknown: " + str(unit_type)) def action(creator, unit_type): unit = creator.make_unit(unit_type) print('The {} is created.'.format(unit.what())) def main(): action(Creator(), UnitTypes.DOG) action(Creator(), UnitTypes.CAT) if __name__ == '__main__': main()
interface Unit {
String what();
}
class Dog implements Unit {
@Override
public String what() {
return "dog";
}
}
class Cat implements Unit {
@Override
public String what() {
return "cat";
}
}
enum UnitTypes {
DOG,
CAT
}
class Creator {
public Unit makeUnit(UnitTypes unitType) throws Exception {
if (unitType == UnitTypes.DOG) {
return new Dog();
} else if (unitType == UnitTypes.CAT) {
return new Cat();
} else {
throw new Exception("unit type is unknown: " + unitType);
}
};
}
class T {
public static void main(String args[]) {
action(new Creator(), UnitTypes.DOG);
action(new Creator(), UnitTypes.CAT);
}
private static void action(Creator creator, UnitTypes unitType) {
try {
Unit unit = creator.makeUnit(unitType);
System.out.printf("The %s is created.\n", unit.what());
} catch (Exception e) {
System.out.println(e);
}
}
}interface Unit {
String what();
}
abstract class Creator {
public abstract Unit makeUnit();
public Unit newUnit() {
return makeUnit();
};
}
class Dog implements Unit {
@Override
public String what() {
return "dog";
}
}
class DogCreator extends Creator {
@Override
public Unit makeUnit() {
return new Dog();
}
}
class Cat implements Unit {
@Override
public String what() {
return "cat";
}
}
class CatCreator extends Creator {
@Override
public Unit makeUnit() {
return new Cat();
}
}
class T {
public static void main(String args[]) {
action(new DogCreator());
action(new CatCreator());
}
private static void action(Creator creator) {
Unit unit = creator.newUnit();
System.out.printf("The %s is created.\n", unit.what());
}
}Отредактировано py.user.next (Март 10, 2019 01:00:48)
Офлайн