2010-12-16 16 views
7

Estoy tratando de aprender y poner en práctica IoC y cómo programar contra interfaces en lugar de objetos. Esto es bastante difícil para mí. Aquí está el código que tengo hasta ahora. ¿Hay algún error que haya cometido? Señalarlos me ayudará a entender cómo encaja realmente cuando se ponga en práctica.¿Este código está desacoplado y lo estoy haciendo bien?

Gracias!

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace SharpDIC.Api.Interfaces 
{ 
    interface IDownloader 
    { 
     void DownloadInformation(); 
    } 
} 



using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using SharpDIC.Api.Interfaces; 

namespace SharpDIC.Api.Models 
{ 
    public class Member 
    { 
     /******************************************************************************** 
     * Some of these attributes aren't even used. The API doesn't provide them yet, * 
     * so I'll have to scrape the information from the HTML itself. Still thinking * 
     * about how to tackle this.             * 
     *                    * 
     * Author: Sergio Tapia               * 
     * Website: http://www.alphaot.com  
     * Date: 16/12/2010 
     * ******************************************************************************/ 

     #region "Attributes" 
     public string ID { get; set; } 
     public string Name { get; set; } 
     public string Rating { get; set; } 
     public string Photo { get; set; } 
     public string LastActive { get; set; } 
     public string Location { get; set; } 
     public string Birthday { get; set; } 
     public string Age { get; set; } 
     public string Gender { get; set; } 
     public string Email { get; set; } 


     public string Title { get; set; } 
     public string Reputation { get; set; } 
     public string DreamKudos { get; set; } 
     public string Group { get; set; } 
     public string Posts { get; set; } 
     public string PostsPerDay { get; set; } 
     public string MostActiveIn { get; set; } 
     public string JoinDate { get; set; } 
     public string ProfileViews { get; set; } 

     public string FavoriteOs { get; set; } 
     public string FavoriteBrowser { get; set; } 
     public string FavoriteProcessor { get; set; } 
     public string FavoriteConsole { get; set; } 

     public List<Visitor> Visitors { get; set; } 
     public List<Friend> Friends { get; set; } 
     public List<Comment> Comments { get; set; } 
     public string ProgrammingLanguages { get; set; } 

     public string Aim { get; set; } 
     public string Msn { get; set; } 
     public string Website { get; set; } 
     public string Icq { get; set; } 
     public string Yahoo { get; set; } 
     public string Jabber { get; set; } 
     public string Skype { get; set; } 
     public string LinkedIn { get; set; } 
     public string Facebook { get; set; } 
     public string Twitter { get; set; } 
     public string XFire { get; set; } 
     #endregion 
    } 

    public class Comment 
    { 
     public string ID { get; set; } 
     public string Text { get; set; } 
     public string Date { get; set; } 
     public string Owner { get; set; } 
    } 

    public class Friend 
    { 
     public string ID { get; set; } 
     public string Name { get; set; } 
     public string Url { get; set; } 
     public string Photo { get; set; } 
    } 

    public class Visitor 
    { 
     public string ID { get; set; } 
     public string Name { get; set; } 
     public string Url { get; set; } 
     public string Photo { get; set; } 
     public string TimeOfLastVisit { get; set; } 
    } 
} 



using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml.Linq; 
using SharpDIC.Api.Interfaces; 
using SharpDIC.Api.Models; 

namespace SharpDIC.Api 
{ 
    public class Wrapper : IDownloader 
    { 
     public void DownloadInformation() 
     { 

     } 

     public Member SearchForMember(int memberID) 
     { 
      XDocument response = GetXmlResponse(memberID); 
      //Member then is responsible to parse and fill his contents. 
      Member member = new Member(response); 
     } 
    } 
} 

¿Qué cambiarías en este código? ¿Lo estoy haciendo bien?

Editar: Observe que el método DownloadInformation() en realidad no está haciendo nada. Mi intención era tener una interfaz con ese método, de esa manera puedo obtener la información del xml (por ahora) pero también puedo cambiar a JSON o lo que el proveedor pueda ofrecer en el futuro.

+1

no veo COI en su código. – VVS

+0

Gracias, tu comentario me ayuda tremendamente./s –

Respuesta

3

¿Qué va a hacer este código?

La manera en que suelo hacer IoC, mis implementaciones están en un ensamblaje separado de mis interfaces. La lógica de negocio solo hace referencia a las interfaces y al contenedor de IoC (StructureMap es mi arma preferida, pero cada una la suya ... incluso podría hacerlo manualmente) conecta las implementaciones.

contrastarlo con lo que tienes aquí hasta ahora:

  1. Su aplicación es en el mismo espacio de nombres (y supongo montaje) como sus interfaces. Aparte de su propia diligencia, realmente no hay nada que le impida programar contra la implementación en lugar de la interfaz. Por lo tanto, el riesgo de acoplamiento todavía existe.
  2. Su implementación tiene un método público que no está en la interfaz. Cualquier cosa que programe contra la interfaz no podrá ver este método. Esto está bien a medida que el sistema crece. No hay razón para que una sola implementación no pueda implementar múltiples interfaces. El principio de segregación de la interfaz lo permite, siempre que las interfaces mismas sean separadas y distintas por algún motivo. Pero si ese método es solo una parte interna de la implementación, private tendría más sentido.

La idea básica detrás de IoC es que una clase debe proporcionarse con una dependencia en lugar de crear una instancia. En este momento, parece que las únicas cosas que crea son XDocument y Member. El primero parece que es solo parte de la implementación interna para IDownloader que extrae la dependencia XML del dominio (interfaz). (Según su edición, eso es correcto. Más adelante puede crear una implementación de IDownloader que maneje JSON en lugar de XML y el dominio no sabrá/cuidará la diferencia). Este último es solo un modelo anémico, así que no veo ningún problema al crear instancias ese.

La parte real de IoC será donde use IDownloader, que no parece que se esté utilizando todavía.

2

Sergio,

algunas cosas que me gustaría cambiar (no tanto basado en el COI - más la especificación de interfaz):

interface IDownloader<T> 
{ 
    T DownloadInformation(); 
} 

esto se siente mejor a mí, a continuación, puede tener ese implementado en su clase concreta algo como:

public class Wrapper : SharpDIC.Api.Interfaces.IDownloader<string> 
{ 
    public Member SearchForMember(int memberID) 
    { 
     XDocument response = GetXmlResponse(memberID); 
     //Member then is responsible to parse and fill his contents. 
     Member member = new Member(response); 
    } 

    public string DownloadInformation() 
    { 
     throw new NotImplementedException(); 
    } 
} 

obviamente, he usado 'cadena' como el tipo pero se puede usar cualquier tipo que necesitaba para la implantación. También me gustaría cambiar de lista de IList:

public IList<Visitor> Visitors { get; set; } 
public IList<Friend> Friends { get; set; } 
public IList<Comment> Comments { get; set; } 

sólo lo hace para un mejor detalle de implementación (después de todo, estamos hablando de las interfaces :-))

Eso es todo - ofertas de respuesta de David con la materia 'inteligente' (bonita David) ...

0

Algunos puntos rápidos (no sobre COI):

Su clase miembro debe ser rediseñado.

Añadir un IList<IInstantMessanger> en lugar de todas las direcciones, como MSN, ICQ, etc. Otra cosa que necesita cambiar su clase cada vez que desee eliminar o añadir un tipo de mensajería instantánea (y por lo tanto romper el principio abierto/cerrado)

Mover favoritos a una clase separada y crea un IList<>. Misma razón.

0

Acerca de los tipos de datos de sus entidades.

  • intenta utilizar otros tipos de datos distintos de cadena Id -> int, Guid
  • Reputación -> es un valor numérico? int, float
  • Lista -> IList -> utilizar interfaces en lugar
Cuestiones relacionadas