Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 需要一些关于我的软件架构的建议。[守则检讨]_C#_.net_Architecture - Fatal编程技术网

C# 需要一些关于我的软件架构的建议。[守则检讨]

C# 需要一些关于我的软件架构的建议。[守则检讨],c#,.net,architecture,C#,.net,Architecture,我正在制作一个开源C#库,供其他开发人员使用。我最关心的是易用性。这意味着使用直观的名称、直观的方法使用等 这是我第一次考虑其他人,所以我非常关心架构的质量。另外,我不介意学一两件事 我有三门课: 下载程序、解析器和电影 我在想,最好只公开我的库的电影类,让下载程序和解析器保持隐藏状态,不被调用 最终,我看到我的库被这样使用 使用FreeIMDB public void Test() { var MyMovie = Movie.FindMovie("The Matrix"); /

我正在制作一个开源C#库,供其他开发人员使用。我最关心的是易用性。这意味着使用直观的名称、直观的方法使用等

这是我第一次考虑其他人,所以我非常关心架构的质量。另外,我不介意学一两件事

我有三门课: 下载程序、解析器和电影

我在想,最好只公开我的库的电影类,让下载程序和解析器保持隐藏状态,不被调用

最终,我看到我的库被这样使用

使用FreeIMDB

public void Test()
{
    var MyMovie = Movie.FindMovie("The Matrix");
    //Now MyMovie would have all it's fields set and ready for the big show.
}
你能回顾一下我是如何计划这件事的,并指出我做出的任何错误判断以及我可以改进的地方吗

记住,我主要关心的是易用性

Movie.cs

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


namespace FreeIMDB
{
    public class Movie
    {
        public Image Poster { get; set; }
        public string Title { get; set; }
        public DateTime ReleaseDate { get; set; }
        public string Rating { get; set; }
        public string Director { get; set; }
        public List<string> Writers { get; set; }
        public List<string> Genres { get; set; }
        public string Tagline { get; set; }
        public string Plot { get; set; }
        public List<string> Cast { get; set; }
        public string Runtime { get; set; }
        public string Country { get; set; }
        public string Language { get; set; }

        public Movie FindMovie(string Title)
        {
            Movie film = new Movie();
            Parser parser = Parser.FromMovieTitle(Title);

            film.Poster = parser.Poster();
            film.Title = parser.Title();
            film.ReleaseDate = parser.ReleaseDate();
            //And so an so forth.
        }

        public Movie FindKnownMovie(string ID)
        {
            Movie film = new Movie();
            Parser parser = Parser.FromMovieID(ID);

            film.Poster = parser.Poster();
            film.Title = parser.Title();
            film.ReleaseDate = parser.ReleaseDate();
            //And so an so forth.
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HtmlAgilityPack;

namespace FreeIMDB
{
    /// <summary>
    /// Provides a simple, and intuitive way for searching for movies and actors on IMDB.
    /// </summary>
    class Parser
    {
        private Downloader downloader = new Downloader();                
        private HtmlDocument Page;

        #region "Page Loader Events"
        private Parser()
        {

        }

        public static Parser FromMovieTitle(string MovieTitle)
        {
            var newParser = new Parser();
            newParser.Page = newParser.downloader.FindMovie(MovieTitle);
            return newParser;
        }

        public static Parser FromActorName(string ActorName)
        {
            var newParser = new Parser();
            newParser.Page = newParser.downloader.FindActor(ActorName);
            return newParser;
        }

        public static Parser FromMovieID(string MovieID)
        {
            var newParser = new Parser();
            newParser.Page = newParser.downloader.FindKnownMovie(MovieID);
            return newParser;
        }

        public static Parser FromActorID(string ActorID)
        {
            var newParser = new Parser();
            newParser.Page = newParser.downloader.FindKnownActor(ActorID);
            return newParser;
        }
        #endregion

        #region "Page Parsing Methods"
        public string Poster()
        {
            //Logic to scrape the Poster URL from the Page element of this.
            return null;
        }

        public string Title()
        {
            return null;
        }

        public DateTime ReleaseDate()
        {
            return null;
        }        
        #endregion        
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统图;
命名空间FreeIMDB
{
公映
{
公共图像海报{get;set;}
公共字符串标题{get;set;}
公共日期时间释放日期{get;set;}
公共字符串评级{get;set;}
公共字符串控制器{get;set;}
公共列表写入程序{get;set;}
公共列表类型{get;set;}
公共字符串标记行{get;set;}
公共字符串绘图{get;set;}
公共列表强制转换{get;set;}
公共字符串运行时{get;set;}
公共字符串国家{get;set;}
公共字符串语言{get;set;}
公共电影FindMovie(字符串标题)
{
电影=新电影();
Parser Parser=Parser.FromMovieTitle(标题);
film.Poster=parser.Poster();
film.Title=parser.Title();
film.ReleaseDate=解析器.ReleaseDate();
//等等。
}
公共电影FindKnownMovie(字符串ID)
{
电影=新电影();
Parser Parser=Parser.FromMovieID(ID);
film.Poster=parser.Poster();
film.Title=parser.Title();
film.ReleaseDate=解析器.ReleaseDate();
//等等。
}
}
}
Parser.cs

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


namespace FreeIMDB
{
    public class Movie
    {
        public Image Poster { get; set; }
        public string Title { get; set; }
        public DateTime ReleaseDate { get; set; }
        public string Rating { get; set; }
        public string Director { get; set; }
        public List<string> Writers { get; set; }
        public List<string> Genres { get; set; }
        public string Tagline { get; set; }
        public string Plot { get; set; }
        public List<string> Cast { get; set; }
        public string Runtime { get; set; }
        public string Country { get; set; }
        public string Language { get; set; }

        public Movie FindMovie(string Title)
        {
            Movie film = new Movie();
            Parser parser = Parser.FromMovieTitle(Title);

            film.Poster = parser.Poster();
            film.Title = parser.Title();
            film.ReleaseDate = parser.ReleaseDate();
            //And so an so forth.
        }

        public Movie FindKnownMovie(string ID)
        {
            Movie film = new Movie();
            Parser parser = Parser.FromMovieID(ID);

            film.Poster = parser.Poster();
            film.Title = parser.Title();
            film.ReleaseDate = parser.ReleaseDate();
            //And so an so forth.
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HtmlAgilityPack;

namespace FreeIMDB
{
    /// <summary>
    /// Provides a simple, and intuitive way for searching for movies and actors on IMDB.
    /// </summary>
    class Parser
    {
        private Downloader downloader = new Downloader();                
        private HtmlDocument Page;

        #region "Page Loader Events"
        private Parser()
        {

        }

        public static Parser FromMovieTitle(string MovieTitle)
        {
            var newParser = new Parser();
            newParser.Page = newParser.downloader.FindMovie(MovieTitle);
            return newParser;
        }

        public static Parser FromActorName(string ActorName)
        {
            var newParser = new Parser();
            newParser.Page = newParser.downloader.FindActor(ActorName);
            return newParser;
        }

        public static Parser FromMovieID(string MovieID)
        {
            var newParser = new Parser();
            newParser.Page = newParser.downloader.FindKnownMovie(MovieID);
            return newParser;
        }

        public static Parser FromActorID(string ActorID)
        {
            var newParser = new Parser();
            newParser.Page = newParser.downloader.FindKnownActor(ActorID);
            return newParser;
        }
        #endregion

        #region "Page Parsing Methods"
        public string Poster()
        {
            //Logic to scrape the Poster URL from the Page element of this.
            return null;
        }

        public string Title()
        {
            return null;
        }

        public DateTime ReleaseDate()
        {
            return null;
        }        
        #endregion        
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用HtmlAgilityPack;
命名空间FreeIMDB
{
/// 
///为在IMDB上搜索电影和演员提供了一种简单直观的方法。
/// 
类解析器
{
私有下载程序下载程序=新下载程序();
私有HtmlDocument页面;
#区域“页面加载程序事件”
专用解析器()
{
}
MovieTitle(stringmovietitle)的公共静态解析器
{
var newParser=newParser();
newParser.Page=newParser.downloader.FindMovie(MovieTitle);
返回newParser;
}
来自ActorName的公共静态解析器(字符串ActorName)
{
var newParser=newParser();
newParser.Page=newParser.downloader.FindActor(ActorName);
返回newParser;
}
公共静态解析器FromMovieID(字符串MovieID)
{
var newParser=newParser();
newParser.Page=newParser.downloader.FindKnownMovie(MovieID);
返回newParser;
}
来自ActorID的公共静态解析器(字符串ActorID)
{
var newParser=newParser();
newParser.Page=newParser.downloader.FindKnownActor(ActorID);
返回newParser;
}
#端区
#区域“页面解析方法”
公共字符串海报()
{
//从页面元素中删除海报URL的逻辑。
返回null;
}
公共字符串标题()
{
返回null;
}
公共日期时间发布日期()
{
返回null;
}        
#端区
}
}
----------------------------------------------- 你们认为我正在朝着一条好的道路前进,还是我在为自己的未来设置一个充满伤害的世界

我最初的想法是将下载、解析和实际填充分离开来,以便轻松地拥有一个可扩展的库。想象一下,如果有一天网站更改了它的HTML,那么我只需修改解析类,而不必碰Downloader.cs或Movie.cs类

谢谢你的阅读和帮助


还有其他想法吗?

我只会公开有意义的项目。对于您的代码,最终结果是电影信息。下载程序和解析器是无用的,除非用于获取电影信息,因此没有理由公开它们

同样,在你的电影课上,我只会让信息变得可获取,而不是太可设置。类没有“保存”功能,因此在获得信息后没有理由编辑信息

除此之外,如果这是针对其他人的,我会评论每个类、成员和每个公共/私有类变量的用途。对于电影类,我可能会在课堂评论中包括一个如何使用它的示例

最后一件事,如果两个私有类中存在错误,则需要以某种方式通知Movie类的用户。可能是一个名为success的公共bool变量

根据个人偏好,对于您的电影类,我希望您的两个函数都是构造函数,这样我就可以按如下方式构建该类

电影myMovie=新电影(“名称”); 或
电影myMovie=新电影(1245)我知道您希望保持API最小化,从而使解析器和下载程序成为私有/内部的,但是您可能需要
public class MovieRepository : IMovieRepository
{
    private readonly IHtmlDownloader _downloader;

    public MovieRepository(IHtmlDownloader downloader)
    {
        _downloader = downloader;
    }

    public Movie FindMovieById(string id)
    {
        var idUri = ...build URI...;

        var html = _downloader.DownloadHtml(idUri);

        return ...parse ID HTML...;
    }

    public Movie FindMovieByTitle(string title)
    {
        var titleUri = ...build URI...;

        var html = _downloader.DownloadHtml(titleUri);

        return ...parse title HTML...;
    }
}
public class NeedsMovies
{
    private readonly IMovieRepository _movies;

    public NeedsMovies(IMovieRepository movies)
    {
        _movies = movies;
    }

    public void DoStuffWithMovie(string title)
    {
        var movie = _movies.FindMovieByTitle(title);

        ...
    }
}
public class TitleHtmlDownloader : IHtmlDownloader
{
    public HtmlDocument DownloadHtml(Uri uri)
    {
        return ...create document from saved HTML...
    }
}

[Test]
public void ParseTitle()
{
    var movies = new MovieRepository(new TitleHtmlDownloader());

    var movie = movies.GetByTitle("The Matrix");

    Assert.AreEqual("The Matrix", movie.Title);

    ...assert other values from the HTML...
}
// Data Contract (or Data Transfer Object)
public class Movie
{
        public Image Poster { get; set; }
        public string Title { get; set; }
        public DateTime ReleaseDate { get; set; }
        public string Rating { get; set; }
        public string Director { get; set; }
        public List<string> Writers { get; set; }
        public List<string> Genres { get; set; }
        public string Tagline { get; set; }
        public string Plot { get; set; }
        public List<string> Cast { get; set; }
        public string Runtime { get; set; }
        public string Country { get; set; }
        public string Language { get; set; }
}

// Movie database searching service contract
public interface IMovieSearchService    
{
        Movie FindMovie(string Title);
        Movie FindKnownMovie(string ID);
}

// Movie database searching service
public partial class MovieSearchService: IMovieSearchService
{
        public Movie FindMovie(string Title)
        {
            Movie film = new Movie();
            Parser parser = Parser.FromMovieTitle(Title);

            film.Poster = parser.Poster();
            film.Title = parser.Title();
            film.ReleaseDate = parser.ReleaseDate();
            //And so an so forth.
        }

        public Movie FindKnownMovie(string ID)
        {
            Movie film = new Movie();
            Parser parser = Parser.FromMovieID(ID);

            film.Poster = parser.Poster();
            film.Title = parser.Title();
            film.ReleaseDate = parser.ReleaseDate();
            //And so an so forth.
        }
}
public abstract class Parser
{
    public abstract IEnumerable<Movie> Parse(string criteria);
}

public class ByTitleParser: Parser
{
    public override IEnumerable<Movie> Parse(string title)
    {
        // TODO: Logic to parse movie information by title
        // Likely to return one movie most of the time, but some movies from different eras may have the same title
    }
}

public class ByActorParser: Parser
{
    public override IEnumerable<Movie> Parse(string actor)
    {
        // TODO: Logic to parse movie information by actor
        // This one can return more than one movie, as an actor may act in more than one movie
    }
}

public class ByIdParser: Parser
{
    public override IEnumerable<Movie> Parse(string id)
    {
        // TODO: Logic to parse movie information by id
        // This one should only ever return a set of one movie, since it is by a unique key
    }
}
public class ParserFactory
{
    public virtual Parser GetParser(string criteriaType)
    {
        if (criteriaType == "bytitle") return new ByTitleParser();
        else if (criteriaType == "byid") return new ByIdParser();
        else throw new ArgumentException("Unknown criteria type.", "criteriaType");
    }
}

// Improved movie database search service
public class MovieSearchService: IMovieSearchService
{
        public MovieSearchService(ParserFactory parserFactory)
        {
            m_parserFactory = parserFactory;
        }

        private readonly ParserFactory m_parserFactory;

        public Movie FindMovie(string Title)
        {
            var parser = m_parserFactory.GetParser("bytitle");
            var movies = parser.Parse(Title); // Parse method creates an enumerable set of Movies that matched "Title"

            var firstMatchingMovie = movies.FirstOrDefault();

            return firstMatchingMovie;
        }

        public Movie FindKnownMovie(string ID)
        {
            var parser = m_parserFactory.GetParser("byid");
            var movies = parser.Parse(Title); // Parse method creates an enumerable set of Movies that matched "ID"

            var firstMatchingMovie = movies.FirstOrDefault();

            return firstMatchingMovie;
        }
}