Pertanyaan Apakah kode ini dipisahkan dan saya melakukannya dengan benar?


Saya mencoba untuk belajar dan mempraktekkan IoC dan bagaimana memprogram terhadap antarmuka bukannya objek. Ini cukup sulit bagiku. Berikut adalah kode yang saya miliki sejauh ini. Apakah ada kesalahan yang saya buat? Arahkan mereka kepada saya akan membantu saya memahami bagaimana itu benar-benar cocok ketika dipraktekkan.

Terima kasih!

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);
        }
    }
}

Apa yang akan Anda ubah dalam kode ini? Apakah saya melakukan ini dengan benar?

Edit: Perhatikan bahwa metode DownloadInformation () sebenarnya tidak melakukan apa-apa. Niat saya adalah memiliki antarmuka yang memiliki metode itu, dengan cara itu saya bisa mendapatkan informasi baik dari xml (untuk saat ini) tetapi juga dapat beralih ke JSON atau apa pun yang mungkin ditawarkan oleh penyedia di masa mendatang.


7
2017-12-16 13:59


asal


Jawaban:


Apa yang akan dilakukan kode ini?

Cara saya cenderung melakukan IOC, implementasi saya berada di majelis terpisah dari antarmuka saya. Logika bisnis hanya referensi antarmuka dan wadah IoC (StructureMap adalah senjata pilihan saya, tetapi untuk masing-masing sendiri ... Anda bahkan bisa melakukannya secara manual) kabel hingga implementasi.

Untuk membedakannya dengan apa yang Anda miliki sejauh ini:

  1. Implementasi Anda dalam namespace yang sama (dan saya menganggap perakitan) sebagai antarmuka Anda. Selain ketekunan Anda sendiri, tidak ada yang menghentikan Anda dari pemrograman terhadap implementasi daripada antarmuka. Jadi risiko kopling masih ada.
  2. Implementasi Anda memiliki metode publik yang tidak ada di antarmuka. Apa pun yang program terhadap antarmuka tidak akan dapat melihat metode ini. Ini bagus karena sistem tumbuh. Tidak ada alasan bahwa implementasi tunggal tidak dapat mengimplementasikan beberapa antarmuka. Prinsip segregasi antarmuka memungkinkan ini, selama antarmuka itu sendiri terpisah dan berbeda karena suatu alasan. Tetapi jika metode itu hanyalah bagian internal dari implementasi, private akan lebih masuk akal.

Ide dasar di balik IoC adalah bahwa kelas harus diberikan dengan ketergantungan daripada instantiate satu. Saat ini, sepertinya satu-satunya hal yang Anda instantiate adalah XDocument dan a Member. Yang pertama terlihat seperti itu hanya bagian dari implementasi internal untuk IDownloader yang menggambarkan ketergantungan XML dari domain (antarmuka). (Berdasarkan hasil edit Anda, itu tepat. Anda nanti bisa membuat IDownloader implementasi yang menangani JSON alih-alih XML dan domain tidak akan tahu / peduli perbedaannya.) Yang terakhir ini hanya model anemik, jadi saya tidak melihat masalah yang menyebabkannya.

Bagian sebenarnya dari IoC adalah tempat yang Anda gunakan IDownloader, yang sepertinya belum digunakan.


3
2017-12-16 14:12



Sergio,

beberapa hal yang akan saya ubah (tidak begitu banyak berdasarkan pada IoC - lebih banyak spesifikasi antarmuka):

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

ini terasa lebih baik bagi saya, Anda kemudian dapat menerapkannya di kelas beton Anda seperti:

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();
    }
}

jelas, saya menggunakan 'string' sebagai tipe tetapi Anda bisa menggunakan jenis apa pun yang Anda butuhkan untuk implementasi. Saya juga akan mengubah Daftar menjadi IList:

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

hanya membuat untuk detail implementasi yang lebih baik (setelah semua, kami sedang mendiskusikan antarmuka :-))

itu semua - jawaban David berkaitan dengan hal-hal yang 'cerdas' (nice one David) ...


2
2017-12-16 14:25



Beberapa poin cepat (bukan tentang ioc):

Kelas anggota Anda harus direfaktor.

Tambah sebuah IList<IInstantMessanger> alih-alih semua alamat seperti Msn, Icq, dll. Lain-lain Anda perlu mengubah kelas Anda setiap kali Anda ingin menghapus atau menambahkan jenis IM (dan karena itu melanggar prinsip Open / Closed)

Pindahkan favorit ke kelas terpisah dan buat a IList<>. Alasan yang sama.


0
2017-12-16 14:31



Tentang tipe data entitas Anda.

  • coba gunakan tipe data lain yang berbeda dari Id string -> int, Guid
  • Reputasi -> adalah nilai numerik? int, float
  • Daftar -> IList -> gunakan antarmuka sebagai gantinya

0
2017-12-16 14:37