Вопрос

Я не могу понять правильные концепции фабрики.

Может ли кто-нибудь помочь мне написать простой тест? Я читаю некоторые тексты через Интернет и не могу кодировать его таким же образом. На самом деле я не могу понять процесс. Копировать код легко, но мне нужно узнать, почему это не сработает.

class Factory:

    def __init__(self):
        self.msg = "teste"

    def fabricateAnotherObject(self,obj,**kwargs):
        return apply(obj,**kwargs)

class testClass:
    def __init__(self,nome,salario,endereco):
        self.nome = nome
        self.salario = salario
        self.endereco = endereco

    def __str__(self):
        return "Nome: " + str(self.nome) + "\nEndereco: " + str(self.endereco) + "\nSalario: " + str(self.salario) 

a = Factory()
emp = a.fabricateAnotherObject(testClass,"George",2000,"Three Four Five Avenue")
print str(emp)
Это было полезно?

Решение

Ваш код контрпродуктивен (извините, я должен это сказать).

Смысл фабрики в том, что вам не нужно знать класс вашего сконструированного объекта в том месте, где вы его создали.

Причина в том, что создание объекта создает пробел в объектно-ориентированной абстракции. Вы должны быть конкретными в создании объекта. Но иногда вы просто хотите создать объект с некоторым поведением, но кто-то другой должен (централизованно) решить, какой это конкретный класс.

Например, вы должны создать один тип объекта в 100 местах. Но позже вы можете узнать, что вы должны изменить класс - вам придется изменить все эти места.

Фабрика устранит эту потребность, определив одно место, которое вы должны изменить.

Самая простая фабрика была бы:

def fabricateAnotherObject(self, **kwargs):
    return testClass(**kwargs)

Конечно, в некоторых ситуациях это может помочь. Поэтому некоторые фабрики могут также загружать имена классов из базы данных или другой конфигурации. Но самое простое решение - это жестко запрограммированная конструкция объекта - в нашем примере необходимо изменить только этот метод, если вы решите всегда вызывать этот метод.

Несколько более динамичное решение (без необходимости в БД):

class Factory(object):
   def __init__(self, theClass):
       self.theClass = theClass
   def create(self, **kwargs):
       self.theClass(**kwargs)

myFactory = Factory(testClass)

Экземпляр myFactory можно использовать в разных местах для создания правильных экземпляров. Проблема в том, как инициализировать myFactory - в каком-то специальном модуле ??

Другие советы

Фабричный шаблон предназначен для языков программирования, которые не допускают функции (и классы) в качестве значений первого порядка (например, C ++ или Java).

Идея состоит в том, что вы передаете экземпляр " фабрики " класс в качестве аргумента некоторой функции (или метода или конструктора), которая затем используется для создания новых экземпляров объекта (обычно это экземпляры некоторого определенного подкласса суперкласса, который известен заранее).

В Python вы можете просто передать класс (поскольку классы (и функции) также являются объектами).

Ваш фабричный метод должен выглядеть следующим образом:

    def fabricateAnotherObject(self, obj, *args):
        return apply(obj, args)

apply () принимает список аргументов. Принимая * args в вашем методе fabricateAnotherObject, вы используете все параметры, кроме obj, в виде списка, который можно передать в apply ().

См. также type () в docs.python.org/library/functions:

тип (имя, основание, дикт)

Вернуть объект нового типа. По сути, это динамическая форма выражения класса. Строка имени является именем класса и становится атрибутом __name__; кортеж base перечисляет базовые классы и становится атрибутом __bases__; а словарь dict - это пространство имен, содержащее определения для тела класса и становится атрибутом __dict__. Например, следующие два оператора создают идентичные объекты типа:

class X(object):
    a = 1
X = type('X', (object,), dict(a=1))

Короткую реальную программу с одним использованием фабрик (компактное создание множества специальных диктов) см. ofc2.py .
Эксперты, больше примеров, пожалуйста?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top