2009-10-13 17 views
15

Estoy haciendo un estudio en profundidad sobre los patrones de diseño, y me encontré con un prototipo, que realmente no estudié antes. He buscado en la web y en varios libros, y no hay un buen ejemplo de prototipo que pueda descubrir que no es solo clonar. ¿El patrón de diseño del prototipo es básicamente una característica del lenguaje de java y C# como clon?¿El patrón de diseño del prototipo es realmente justo?

+3

Los patrones son abstracciones independientes del lenguaje, el clon es una expresión idiomática específica. Sería correcto decir que el patrón del Prototipo es una generalización de la expresión idiomática del clon, o que el clon es una expresión idiomática específica del idioma del Prototipo, pero sería un error vincularlo estrechamente a un idioma de un solo idioma. –

Respuesta

18

El patrón Prototype es mucho más que Clone. La semántica de clones es más amplia, lo que significa que los campos escalares/valores de una instancia de objeto se duplican en una nueva instancia, de modo que tienen el estado equivalente pero ocupan diferentes ubicaciones en la memoria. El clon puede usarse para soportar muchas necesidades diferentes.

El patrón Prototype incorpora Clone específicamente para resolver el gran problema de separar la construcción de objetos del uso de objetos. La semántica del prototipo indica que el único método (o al menos el compatible/preferido) para construir un nuevo objeto de comportamiento requerido es Clonando una instancia particular, conocida como la instancia del prototipo. Estas instancias de prototipo pueden vivir en una fábrica de prototipos, que se implementa para crear nuevas instancias llamando a Clone en las instancias del prototipo. Las instancias del prototipo se pueden inicializar a través de la inyección de dependencia. El código de inyección es el único código que necesita saber cómo construir las instancias de prototipo, y esto se convierte efectivamente en el código de fábrica real.

Esperemos que la siguiente clase de fábrica ejemplo aclara el punto crucial del patrón:

public class PrototypeWidgetFactory : IWidgetFactory 
{ 
    public PrototypeWidgetFactory(PrototypeWidget scenarioA, PrototypeWidget scenarioB, PrototypeWidget scenarioC) 
    { 
    _scenarioA = scenarioA; 
    _scenarioB = scenarioB; 
    _scenarioC = scenarioC; 
    } 

    public Widget GetForScenarioA() { return _scenarioA.Clone(); } 
    public Widget GetForScenarioB() { return _scenarioB.Clone(); } 
    public Widget GetForScenarioC() { return _scenarioC.Clone(); } 

    private PrototypeWidgetFactory _scenarioA; 
    private PrototypeWidgetFactory _scenarioB; 
    private PrototypeWidgetFactory _scenarioC; 
} 

Una instancia de esta fábrica se puede pasar allí donde se necesite IWidgetFactory. La ventaja es que no necesita un grupo de diferentes clases de fábrica para cada comportamiento. De hecho, para ciertos tipos de comportamiento, ni siquiera necesita un grupo de clases diferentes si solo inyecta instancias del mismo tipo que se inicializan de manera diferente en la fábrica de prototipos. En este caso, la ventaja es aún mayor, ya que la API no se hincha con un grupo de clases pequeñas que no hacen mucho.

El inconveniente es que el código de inyección necesita saber cómo construir los prototipos. Esto es frágil si hay mucha lógica compleja involucrada en la construcción de los prototipos.

(Nota: el patrón Prototype no requiere que todos los métodos en una fábrica de prototipos devuelvan el mismo tipo. Acabo de hacer que el ejemplo devuelva solo Widgets porque eso demuestra la mayor ventaja de usar prototipos para construir objetos para un comportamiento particular cuando el los objetos son de un tipo pero se inicializaron de manera diferente.)

public class PrototypeDomainFactory : IDomainFactory 
{ 
    public PrototypeDomainFactory(PrototypePerson personPrototype, PrototypeCompany companyPrototype, PrototypeWidget widgetPrototype) 
    { 
    _personPrototype = personPrototype; 
    _companyPrototype = companyPrototype; 
    _widgetPrototype = widgetPrototype; 
    } 

    public Person GetPerson() { return _personPrototype.Clone(); } 
    public Company GetCompany() { return _companyPrototype.Clone(); } 
    public Widget GetWidget() { return _widgetPrototype.Clone(); } 

    private PrototypePerson _personPrototype; 
    private PrototypeCompany _companyPrototype; 
    private PrototypeWidget _widgetPrototype; 
} 
0

Clone() es definitivamente parte de él. Creo que el patrón también habla de que hay maneras de recolectar objetos, iterar a través de ellos y encontrar el correcto para clonar. También debe configurar los objetos para comenzar.

4

Sorta. Clone() hace mucho de lo que quiere para prototipos, pero puede ir mucho más allá con el patrón si es necesario. Vea Steve Yegge's deep (and lengthy!) explanation, o estudie el modelo de objetos Javascript.

+1

Eso no es prototipo - (aunque definitivamente está relacionado) - lo llama el Patrón de Propiedades. En JavaScript, la palabra "prototipo" se usa para describir parte de esto, y la clonación está definitivamente involucrada, pero aún pienso en ellos como cosas diferentes. El prototipo en GoF no habla de la idea de las propiedades dinámicas. –

+0

Ese es un punto justo.Siempre he pensado que Prototype abarca cosas como propiedades dinámicas e iterabilidad, simplemente porque si no lo es * es * básicamente Clone(), y eso parece cojo. –

+0

Wow, gracias por publicar esa entrada en el blog. Muy buena lectura Aprendí mucho leyendo eso. Estoy de acuerdo en que no es el patrón de prototipo descrito en el libro de GoF. –

Cuestiones relacionadas