Какой шаблон проектирования решает проверку нескольких правил? - PullRequest
1 голос
/ 29 марта 2019

Я хочу сохранить некоторые файлы статьи, которые публикуются в ядре ASP.NET MVC Core.Тогда у меня есть они как IFormFile в HttpContext.Эти файлы могут быть изображения, видео и документа.Каждый из этих файлов имеет свои ограничения для сохранения, такие как размер или расширение, и у каждого типа могут быть свои определенные ограничения.Например, основное изображение статьи не должно быть больше 1500 * 900. Поэтому я решил поставить им такой дизайн:

Class Diagram

И мои коды:

public interface IArticleFile
{
    void CheckFileRules(IFormFile formFile);
    void SaveFile(IFormFile formFile, string path);
}

public interface IArticleImage : IArticleFile
{
    void CheckImageRules(IFormFile formFile);
}

public interface IArticleVideo : IArticleFile
{
    void CheckVideoRules(IFormFile formFile);
}

public class ArticleMainImage: IArticleImage
{
    public void CheckFileRules(IFormFile formFile) {/*CHECK STH*/}
    public void CheckImageRules(IFormFile formFile) {/*CHECK STH*/}
    public void SaveFile(IFormFile formFile, string path) { /* Save file */ }
}
public class ArticleSummaryImage : IArticleImage
{
    public void CheckFileRules(IFormFile formFile) {/*CHECK STH*/}
    public void CheckImageRules(IFormFile formFile) {/*CHECK STH*/}
    public void SaveFile(IFormFile formFile, string path) { /* Save file */ }
}

public class ArticleDto
{
    /*some properties*/
    public IFormFile MainImage { get; set; }
    public IFormFile SummaryImage { get; set; }
    public IFormFile ThumbnailImage { get; set; }
    public List<IFormFile> Videos { get; set; }
    public List<IFormFile> Documents { get; set; }

}

public class Article: IArticleService
{
    public void AddArticle(ArticleDto articleDto)
    {
        var articleMainImage = new ArticleMainImage();
        articleMainImage.CheckFileRules(articleDto.MainImage);
        articleMainImage.CheckImageRules(articleDto.MainImage);

        var articleSummaryImage = new ArticleMainImage();
        articleSummaryImage.CheckFileRules(articleDto.MainImage);
        articleSummaryImage.CheckImageRules(articleDto.MainImage);

        //Do these for Thumbnail image, videos, and documents
    }
}

Но, я думаю, мне следует использовать здесь шаблон проектирования, чтобы впоследствии им было легче манипулировать, чтобы не повторять некоторые из моих кодов в слое Service.Как я могу сделать это лучше?

1 Ответ

1 голос
/ 30 марта 2019

Вы можете использовать Command шаблон проектирования, изменив некоторую часть вашего кода. Здесь вы можете иметь два типа команд. 1-й для вашей проверки и 2-й для сохранения файла. Таким образом, зарегистрировав их в качестве команды, вы можете вызвать их всех в одном месте. Вы можете использовать класс .NET Action в качестве команды и использовать его в классе CommandHandler:

Итак, если у вас есть такой класс обработчика команд:

public class CommandsHandler
{
    private List<Action> Commands { get; set; }

    public void AddCommand(Action saver)
    {
        Commands.Add(saver);
    }

    public void ExecuteAll()
    {
        Commands.ForEach(c => c.Invoke());
    }
}

Затем измените ваши классы статей, чтобы получить обработчик команд. Обратите внимание, что каждый суперкласс отвечает за регистрацию методов проверки, чтобы предотвратить повторную регистрацию у детей:

public abstract class ArticleFile
{
    protected IFormFile FileForm;
    protected string FileFullPath;
    public abstract void CheckFileRules();

    public void SaveFile(){

    protected ArticleFile(CommandsHandler validator, CommandsHandler saver, IFormFile file, string path)
    {
        FileForm = file;
        FileFullPath = path;
        validator.AddCommand(CheckFileRules); 
        saver.AddCommand(SaveFile); 
    }
}

public abstract class ArticleImage : ArticleFile
{
    public abstract void CheckImageRules();

    protected ArticleImage(CommandsHandler validator, CommandsHandler saver, IFormFile file, string path)
        : base(validator, saver, file, path)
    {
        validator.AddCommand(CheckImageRules);
    }
}

public class ArticleVideo : ArticleFile
{
    public override void CheckFileRules() {/*CHECK STH*/ }

    public void CheckVideoRules() {/*CHECK STH*/ }

    public ArticleVideo(CommandsHandler validator, CommandsHandler saver, IFormFile file, string path)
        : base(validator, saver, file, path)
    {
        validator.AddCommand(CheckVideoRules);
    }
}

public class ArticleMainImage : ArticleImage
{
    public ArticleMainImage(CommandsHandler validator, CommandsHandler saver, IFormFile file, string path)
        : base(validator, saver, file, path)
    {
        validator.AddCommand(CheckImageDimensions);
    }
    public override void CheckFileRules() {/*CHECK STH*/}
    public override void CheckImageRules() {/*CHECK STH*/}

    public void CheckImageDimensions() { }


}

Тогда вы можете легко создавать свои объекты и вызывать валидаторы и заставки:

public class Article : IArticleService
{
    public void AddArticle(ArticleDto articleDto)
    {
        var articleValidator = new CommandsHandler();
        var articleFileSaver = new CommandsHandler();
        var articleMainImage = new ArticleMainImage(articleValidator, articleFileSaver, articleDto.MainImage, "");

        var articleVideos = new List<ArticleVideo>();
        articleDto.Videos.ForEach(v =>
            articleVideos.Add(new ArticleVideo(articleValidator, articleFileSaver, v, "")));

        articleValidator.ExecuteAll();
        articleFileSaver.ExecuteAll();
    }
}
...