visual usan una tomar toma tener studio sobre saber que programar programacion principiantes principales para orientada objetos net métodos manejo los lista libros librería lenguaje invocar introducción introduccion gerentes facil eventos evento empresariales desde delegados decisión decisiones decision debo cuenta cuatro conociendo conceptos cero biblioteca aprende analisis c# design-patterns oop io

c# - usan - ¿Debería un objeto escribirse a sí mismo en un archivo, o debería actuar sobre él otro objeto para realizar E/S?



tomar una decisión (7)

Creo que el enfoque correcto es el Caso 1, pero su clase se puede definir de esta manera para aprovechar ambos enfoques:

class Bob { IWriter _myWriter = null; public Bob(){ // This instance could be injected or you may use a factory // Note the initialization logic is here and not in Save method _myWriter = new Writer("c://bob.xml") } //... public void Save(){ _myWriter.Write(this); } // Or... public void Save(string where){ _myWriter.Write(this, where); } //... }

Esto podría modificarse fácilmente para poner la lógica de escritura y la inicialización en una clase base para que la clase Bob sea aún más limpia e independiente de la persistencia.

NOTA: ¡Perdón por la larga pregunta!

Intento entender algunas áreas clave detrás de la orientación a objetos y no pude decidir de una forma u otra sobre mi pregunta en particular.

Digamos que tengo un objeto lleno de datos encantadores. Clase bob.

Bob myBob = new Bob("This string is data");

Digamos que quiero guardar los contenidos de myBob en un archivo xml (bob.xml)

¿Debo hacer que un objeto actúe en bob para escribir el contenido, o debo hacer que myBob haga esto?

Caso 1: Actuar sobre el objeto

Writer myWriter = new Writer(myBob, "C://bob.xml");

Caso 2: método de ahorro

myBob.Save("C://bob.xml");

Algunas personas se están alineando con la opción uno ya que significa que si se cambia el código para escribir archivos, no es necesario que se actualice en todos los métodos de Guardar; promoviendo la reutilización del código, supongo. Mi problema con esto es obtener todos los datos de los objetos que pueden tener datos privados sin acceso.

El caso para la opción dos es que el método solo actúa sobre los datos contenidos en el objeto y así es como debería ser. Sin interferencias de otros objetos.

¿O la respuesta a mi pregunta es una de esas cuestiones "dependientes del caso"? Si es así, ¿cómo sabes cuándo se prefiere un método al otro?


El enfoque correcto, en general, es su Caso 1. Esto mantiene una responsabilidad única para la clase (lo que sea que haga) sin asociarla a un mecanismo de persistencia específico (un disco).

Está viendo un caso específico de un problema más generalizado: la serialización. Está bien y está bien que un objeto tenga algún medio para indicar cómo se debe serializar; después de todo, es la única entidad que sabe qué es necesario para deserializarlo. Pero si hace que el objeto se guarde solo en el disco, ha acoplado firmemente ese objeto a una implementación específica.

En su lugar, considere la posibilidad de crear una interfaz que un "escritor" generalizado pueda usar para "serializar" el objeto a lo que serialice ese escritor. De esta forma, podrá serializar en el disco, en la red, en la memoria, o en lo que necesite serializar. :)


Este es un ejemplo de dónde podría utilizarse el Patrón de diseño de estrategia . Su objeto myBob podría tener una instancia de la clase que lo va a escribir. Es posible que desee que el escritor implemente una interfaz o provenga de una clase abstracta para que la rutina de guardado se pueda cambiar fácilmente.
Hoy estás guardando en xml, pero es posible que también necesites persistir el objeto en una base de datos. Este patrón le permitirá cambiar fácilmente la rutina de guardado. Incluso tendrías la opción de cambiar la forma de guardar en tiempo de ejecución.


Hacer esto:

public interface Writable { public void Save(Writer w); } public interface Writer { public void WriteTag(String tag, String cdata); } public class Bob : Writable { private String ssn = "123-23-1234"; public void Save(Writer w) { w.WriteTag("ssn", ssn); } } public class XmlWriter : Writer { public XmlWriter(Sting filename) {...} public void WriteTag(String tag, Sting cdata) {...} }

Obviamente, esta no es una solución completa, pero debería tener una idea general.


Haría que Bob sepa cómo serializarse, ya que tiene datos privados. Otro objeto (como su Writer ) tomaría eso y lo pondría en el disco. Bob sabe cómo manejar mejor sus datos, pero no tiene que importar cómo o dónde se almacenan. Su escritor sabe cómo guardar mejor los datos, pero no le importa cómo se crean esos datos.


Otro método es usar el patrón de visitante. Haga que su objeto contenga un método de Aceptar que atraviesa los miembros que desea procesar / serializar y que un visitante sea su serializador. Cada vez que actualice o cambie su serialización (texto plano a xml a binario a lo que sea), no necesita actualizar el objeto.

Hemos tenido buenas experiencias en el trabajo haciéndolo de esta manera. Es bastante poderoso.


Yo solía preferir la opción 2; sin embargo, como he comenzado a tratar de entender y modelar los dominios en los que estoy trabajando, prefiero la opción 1.

Imagina si tus vehículos de modelado. ¿Por qué un vehículo sabría cómo persistir? Puede saber cómo moverse, cómo empezar y cómo detenerse, pero qué es Guardar en el contexto de un vehículo.