2009-08-10 10 views
6

Recientemente estoy trabajando en una estructura de árbol, varios nodos, niveles múltiples y aumentables, y un método de impresión(). Al principio, pensé que debería ser un compuesto, i entonces por escrito algún diseño posible y códigos:¿Qué ventaja me traerá el patrón compuesto solo por Array?

alt text

$struc = new Node(‘name0’, ‘id0’, ‘desc0’); 
$node1 = new Node(‘node1’, ‘id1’, ‘desc1’); 
$node2 = new Node(‘node2’, ‘id2’, ‘desc2’); 
$node3 = new Node(‘node3’, ‘id3’, ‘desc3’); 
$leaf1 = new Leaf(‘leaf1’, ‘ld1’, ‘lesc1’); 
$leaf2 = new Leaf(‘leaf2’, ‘ld2’, ‘lesc2’); 
$leaf3 = new Leaf(‘leaf3’, ‘ld3’, ‘lesc3’); 
$leaf4 = new Leaf(‘leaf4’, ‘ld4’, ‘lesc4’); 

$struc.add($node1); 
$struc.add($node3); 

$node1.add($leaf1); 
$node1.add($leaf2); 
$node1.add($node2); 

$node2.add($leaf3);  
$node3.add($leaf4); 

Se ve bien, pienso y comenzar la codificación, el método de impresión() puede seguir iterador patrón más tarde. Pero durante la codificación, ¿me parece demasiado complejo para estos nodos simples? Y tengo que instanciar muchas clases concretas (más de 50 o más, y aumentando). entonces me detuve y pensar de una manera similar sencilla mediante el uso de matriz:

-- Structure Class -- 
//To be more readable and clear, array here could be 
//divided to 3 arrays(root/nodes/leafs), then connect 
//in a similar way Composite does. 
$struc = array('name0', 'id0', 'desc0', 

      'children'=>array(

       array('node1', 'id1', 'desc1', 
        'children' => array(
        array('leaf1', 'ld1', 'lesc1'), 
        array('leaf2', 'ld2', 'lesc2'), 
        array('node2', 'id2', 'desc2', 
         'children'=>array(array('leaf3', 'ld3', 'lesc3')) 
        ) 
       ) 
       ), 

       array('node3', 'id3', 'desc3', 
        'children' => array(array('leaf4', 'ld4', 'lesc4')) 
       ) 
      ) 
); 

function print($node = $this->struct) { 
    ... 
    if(isset($node['children'])) $this->print($node['children']); 
    ... 
} 

Los dos diseños son muy similares, ahora estoy un poco confundido, ¿cuál es el valor del patrón Composite, ¿estoy perdido algo importante de este patrón ?

+2

Mi conclusión: Design Pattern es genial, pero no significa que siempre se prefieran. En este ejemplo, dado que el árbol tiene más de 1000 nodos, un implemento compuesto necesita que el cliente instancia más de 1000 objetos, ¿entonces qué? debe abordar otro patrón Flyweight para mejorar el rendimiento y ahorrar recursos. El programa se vuelve más y más complejo, por fin, un Compuesto + Iterador + Flyweight (+ Vistor a veces) implementan. En un problema simple que puede ser resuelto por una clase con una matriz y un método. Finalmente, en esta pregunta, mi respuesta es: Array implementar derrotas Pattern implementar. – Edward

Respuesta

6

El objetivo de composite pattern es poder tratar una colección de objetos como si fuera un solo objeto (por ejemplo, para mostrarlo o escribirlo en un archivo). Al escribir usted mismo "el método print() puede seguir el patrón Iterator más tarde" - bueno, el punto del patrón compuesto sería que usted podría llamar a print() sin tener que preocuparse de si está imprimiendo un solo componente o tiene que iterar a través de un Árbol entero.

Pero parece que no está claro acerca de la programación orientada a objetos en general, ya que está considerando utilizar matrices anidadas en su lugar. El valor de usar objetos en lugar de hashes (que las matrices PHP son) para todo es type safety, lo que hace que sea mucho más fácil depurar y mantener programas.

+0

Tiene razón, yo era un programador de C desde hace mucho tiempo, cuando en la programación OO, sigo muchos principios y patrones porque sé que son importantes, pero realmente no sé por qué son importantes . Según entiendo, OO es sobre todo la manera de hacer que el programa sea fácil de mantener para cambiar, pero generalmente no puedo ver, incluso no sé si es efectivo. en este ejemplo, por ejemplo, todavía no puedo ver cómo se supone que el precio más bajo que se supone que proporciona Composite, agregar/eliminar nodos, cambiar el orden, ¿no son los dos cambios de códigos los mismos? – Edward

+0

Piénselo de esta manera: el uso de matrices en lugar de objetos es similar a un programa en C que usa void * para todos los parámetros del método. –

+0

Siento de ti una manera diferente de pensar, pensar en el implemento Array, creo que es un implemento OO, simplemente no compuesto, ¿no es así? Puedo entender el ejemplo que dijo, pero no me sirve de ayuda usar objetos en lugar de una matriz, en este ejemplo, los beneficios. – Edward

7

el valor de compuesto es que intercambia alguna complejidad por no poder romper la encapsulación.

En la versión de serie que está violando la encapsulación ya que son prueba si el nodo no es una hoja:

if(isset($node['children'])) $this->print($node['children']); 

con composite se puede decir:

print(); 

continuación polimorfismo en tiempo de ejecución llamará al método correcto. En este caso (no soy un programador PHP así que yo use una sintaxis similar a Java):

class Node { 

    void print() { 
     for (child in children) { 
      child.print(); 
     } 
    } 

    ... 
} 

class Leaf { 

    void print() { 
     // print it! 
    } 
} 

otra ventaja sobre array plano es que son ocultar su detalles de implementación (estructura de datos, etc.)

+0

Traté de entender, pero todavía no puedo captar el espíritu. Debajo están mis pensamientos, pueden señalar mis errores, también corregí algunos errores en mis códigos. 1. "romper encapsulación", lo que estoy confundido es si no trato al nodo como una entidad, ¿sigue siendo una ruptura de la encapsulación? y ¿qué problema causará al fin? 2. Creo que los detalles de implementación están ocultos en la clase Estructura, ¿no es así? 3. Todavía no puedo encontrar la ventaja de Composite, no importa cómo modifique este árbol, los precios de los cambios de código adoptados de dos maneras parecen ser los mismos. – Edward

+0

ahora el código se ve mejor: 1. con el compuesto no se distinguen las operaciones en los nodos de las operaciones en hojas 2. ahora está claro que su matriz está encapsulada en una clase; en su pregunta original no es – dfa

0

¿La implementación de la matriz no te parece mucho más compleja? Si lo estoy mirando, tengo que estudiarlo más de cerca para entender lo que estás haciendo. Estás tratando con índices, asignando entradas a índices específicos, etc. ... parece realmente complejo.

Su implementación del patrón compuesto en el otro sitio parece simple y natural cuando mira el código donde lo está usando. Tienes un nodo y le adjuntas otros nodos o hojas. Nada complejo, extraño, no tengo que importar/recordar índices, etc. Es por eso que el patrón compuesto es útil en su caso. Por supuesto, su implementación puede parecerle un poco compleja, si no está acostumbrado, pero el punto importante (como también se dijo) es que está ocultando detalles.Esto es muy importante. Es un ejemplo simple de que aún puede funcionar con sus matrices, pero cuando implemente dicho código en un entorno de producción donde posiblemente también otros desarrolladores estén editando/manteniendo su código. Si alguien tiene que modificar su solución de "matriz", es mucho más probable que introduzca nuevos errores.

+0

Corregí algunos errores en los códigos anteriores, ahora debería estar más cerca de mi mente. – Edward

Cuestiones relacionadas