2011-08-02 13 views
5

he estado leyendo recientemente y se han encontrado con la Ley de Demeter. Ahora, algo de lo que he leído tiene perfecto sentido, por ej. el repartidor de periódicos nunca debería poder buscar en el bolsillo de un cliente, agarrar la billetera y sacar el dinero. La billetera es algo que el cliente debe tener control, no el paperboy.Ley de Demeter y programación orientada a objetos confusión

Lo que me lanza sobre la ley, tal vez sólo estoy malentendido todo esto, es que encadenar propiedades junto con una jerarquía de funcionalidad/información puede ser tan útil. p.ej. .NET clase HTTPContext.

No sería codificar tales como:

If DataTable.Columns.Count >= 0 Then 
    DataTable.Columns(0).Caption = "Something" 
End If 

O

Dim strUserPlatform as string = HttpContext.Current.Request.Browser.Platform.ToString() 

O

If NewTerm.StartDate >= NewTerm.AcademicYear.StartDate And 
    NewTerm.EndDate <= NewTerm.AcademicYear.EndDate Then 
    ' Valid, subject to further tests. 
Else 
    ' Not valid. 
End If 

rompe esta ley? Pensé (quizás por error) que el objetivo de OOP era, en parte, proporcionar acceso a las clases relacionadas en una buena estructura jerárquica.

me gusta, por ejemplo, la idea de la referencia a un conjunto de herramientas de utilidad que puede ser utilizado por las clases de página para evitar tareas repetitivas, tales como el envío de mensajes de correo electrónico y encapsular métodos de cadena útiles:

Dim strUserInput As String = "London, Paris, New York" 
For Each strSearchTerm In Tools.StringManipulation.GetListOfString(strUserInput, ",") 
    Dim ThisItem As New SearchTerm 
    ThisItem.Text = strSearchTerm 
Next 

Cualquier claridad sería genial ... en este momento no puedo conciliar cómo la ley parece desterrar las propiedades y los métodos de unión ... ¿me parece extraño que se desatienda tanto poder? Soy bastante nuevo en la POO como algunos de ustedes habrán adivinado, así que por favor vaya fácil :)

+5

Estas "leyes" no son leyes reales. A diferencia de las leyes de la termodinámica, puedes doblarlas y romperlas cuando lo desees. Para no volverse loco, trate de considerarlo como la "guía" de Demeter, si lo sigue religiosamente terminará trabajando para él, sin hacerlo funcionar para usted. Todas las cosas con moderación ... Incluyendo la moderación. –

+0

^--------- ¡Eso! – Dan

+0

Gracias Binary :) –

Respuesta

6

Lo que la Ley de Demeter (también "Ley de Demeter para Funciones/Métodos") quiere reducir diciendo "solo use un punto" es que en un método no debería tener que asumir un contexto tan amplio los argumentos proporcionados. Esto aumenta la dependencia de la clase y la hace menos comprobable.

Esto no quiere decir que no se puede usar todos los ejemplos anteriores pero sugiere que en lugar de dar a su método el cliente que a su vez tiene acceso a la carpeta y recupera el dinero de él:

function getPayment(Customer customer) 
{ 
    Money payment = customer.leftpocket.getWallet().getPayment(100); 
    ... 
    // do stuff with the payment 
} 

que en vez pasa únicamente lo que el repartidor tiene que el método y, como tal, reducir la dependencia del método si es posible:

function getPayment(Money money) 
{ 
    // do stuff with the payment 
} 

Su beneficio de ello será que usted no depende de que el cliente tenga la cartera en el bolsillo izquierdo, pero en su lugar solo proces s el dinero que el cliente le da. Sin embargo, es una decisión que debe basarse en su caso individual. Menos dependencias le permiten realizar pruebas más fácilmente.

+0

Gracias por eso, tiene sentido para mí que un objeto no sepa demasiado sobre otro objeto cuando no es necesario. Usando el primer ejemplo, otras clases como Window Cleaner que pueden insertarse en ese sistema en el futuro tendrán que tener la misma declaración Money payment = customer.leftpocket.getWallet(). GetPayment (100), a menos que haga lo que se sugiere y darle al cliente un método getPayment para comenzar. –

+0

+1:^--------- ¡Eso! en efecto :) –

3

creo que la aplicación de la Ley de Demeter a las clases individuales se lo está tomando un poco demasiado lejos. Creo que una mejor aplicación es aplicarlo a capas en su código. Por ejemplo, su capa de lógica de negocios no debería tener que acceder a nada sobre el contexto HTTP, y su capa de acceso a datos no debería necesitar acceder a nada en la capa de presentación.

Sí, es por lo general buenas prácticas para diseñar la interfaz de su objeto, de manera que usted no tiene que hacer toneladas de encadenamiento de propiedad, pero se imagina el terriblemente compleja interfaz que tendría si se trató de hacer eso a las clases DataTable y HttpContext que proporcionó como ejemplos.

+0

Estoy de acuerdo con ambos que al diseñar clases como el ejemplo de paperboy, se debe tener cuidado de no tener una situación donde lo que realmente debería ser la funcionalidad del cliente se convierta en parte del repartidor, también se acuerde que las capas deben mantenerse separado de la manera que sugieres. –

1

La ley no dice que usted no debe tener acceso a cualquier información en absoluto en una clase, pero que sólo se debe tener acceso a la información de una manera que no se puede hacer mal uso fácilmente.

Por ejemplo, puede no agregar columnas en una tabla de datos mediante la asignación de nada a la Count propiedad:

DataTable.Columns.Count = 42; 

En lugar de utilizar el método del objeto Columns que le permite agregar una columna de una manera Add que toda la información necesaria sobre la columna está allí, y también para que la tabla de datos se configure con datos para esa columna.

Cuestiones relacionadas