В этой статье рассматриваются такие дополнительные паттерны, которые не вошли в "Банду четырёх", но применяются в разработке приложений. К ним можно отнести такие паттерны, как «Abstract Document», «Active Object», «Acyclic Visitor», «Balking», «Bytecode», «Caching», «Callback», «Async Method Invocation», «Context Object», «Converter», «Data Access Object», «Data Transfer Object», «Dirty Flag», «Double Buffer», «Event Queue», «Execute Around», «Monad», «Mono State», «Mute Idiom», «Naked Objects», «Null Object», «Object Mother», «Object Pool», «Parameter Object» и многие другие.

Абстрактный документ (Abstract Document)

Паттерн «Абстрактный документ» - это структурный паттерн, который реализует обработку иерархических и древовидных структур для документов с разными типами. Он позволяет прикреплять к объектам свойства без их ведома.

Паттерн использует концепцию свойств, чтобы обеспечить безопасность типов и разделить свойства разных классов на наборы интерфейсов.

Абстрактный документ
Абстрактный документ

Суть в том, что вариация документов достигается с помощью общего интерфейса, а иерархичность - с использованием Dictionary<String, Object>. В результате объект содержит карту свойств и любое количество дочерних объектов.

Определим общий интерфейс, а также базовую реализацию таких действий, как добавление пары «Строка-Объект», получение объекта по ключу и получение дочерних элементов.

Определение интерфейса и операций
public interface IDocument
{
    public void Put(string key, object value);

    public object Get(string key);

    public List<Dictionary<string, object>> Children(string key);
}

public abstract class AbstractDocument : IDocument
{
    protected Dictionary<string, object> Dictionary;

    protected AbstractDocument(Dictionary<string, object> keyValuePairs)
    {
        this.Dictionary = keyValuePairs;
    }

    public List<Dictionary<string, object>> Children(string key)
    {
        List<Dictionary<string, object>> results = new();

        if (Get(key) is not List<Dictionary<string, object>> childrens) 
        {
            return results;
        }

        foreach (Dictionary<string, object> children in childrens)
        {
            results.Add(children);
        }

        return results;
    }

    public object Get(string key)
    {
        return Dictionary[key];
    }

    public void Put(string key, object value)
    {
        Dictionary.Add(key, value);
    }
}

Определим перечисление Property и набор интерфейсов для основных характеристик. Это позволит реализовать любой тип документа.

Определение перечисления и интерфейсов
public enum Property
{
    Parts, Chars, Rows, Colls, Type, Version
}

public interface IParts : IDocument
{
    public object GetParts();
}

public interface IChars : IDocument
{
    public int GetChars();
}

public interface IType : IDocument
{
    public string GetType();
}

public interface IRows : IDocument
{
    public int GetRows();
}

public interface IColls : IDocument
{
    public int GetColls();
}

public interface IVersion : IDocument
{
    public int GetVersion();
}

Определим разные типы документов с помощью AbstractDocument и тех интерфейсов, которые были заданы выше.

Определение реализации документов
public class TextDocument : AbstractDocument, 
  IParts, IChars, IType, IVersion
{
    public TextDocument(Dictionary<string, object> keyValuePairs) 
      : base(keyValuePairs)
    {
        this.Dictionary = keyValuePairs;
    }

    public int GetChars()
    {
        return (int)this.Dictionary[Property.Chars.ToString()];
    }

    public object GetParts()
    {
        return this.Dictionary[Property.Parts.ToString()];
    }

    public int GetVersion()
    {
        return (int)this.Dictionary[Property.Version.ToString()];
    }

    public new string GetType()
    {
        return (string)this.Dictionary[Property.Type.ToString()];
    }
}

public class TableDocument : AbstractDocument, 
  IType, IRows, IColls, IVersion
{
    public TableDocument(Dictionary<string, object> keyValuePairs) 
      : base(keyValuePairs)
    {
        this.Dictionary = keyValuePairs;
    }

    public new string GetType()
    {
        return (string)this.Dictionary[Property.Type.ToString()];
    }

    public int GetRows()
    {
        return (int)this.Dictionary[Property.Rows.ToString()];
    }

    public int GetColls()
    {
        return (int)this.Dictionary[Property.Colls.ToString()];
    }

    public int GetVersion()
    {
        return (int)this.Dictionary[Property.Version.ToString()];
    }
}

Пробуем создать текстовый файл. Он содержит базовые характеристиками: тип, версия, количество символов, а также табличный файл. Табличный файл имеет версию, тип, количество строк и столбцов.

Использование паттерна
private static void Main(string[] args)
{
    Dictionary<string, object> tableDocumentProperties = new()
    {
        { Property.Version.ToString(), 1 },

        { Property.Rows.ToString(), 10 },

        { Property.Colls.ToString(), 5 },

        { Property.Type.ToString(), ".xslx" }
    };

    Dictionary<string, object> textDocumentProperties = new()
    {
        { Property.Version.ToString(), 1 },

        { Property.Chars.ToString(), 10000 },

        { Property.Type.ToString(), ".docx" },

        {
            Property.Parts.ToString(),
            new List<Dictionary<string, object>>() { tableDocumentProperties }
        }
    };

    TextDocument textDocument = new(textDocumentProperties);

    Console.WriteLine(textDocument.GetType());

    Console.WriteLine(textDocument.GetVersion());

    Console.WriteLine(textDocument.GetChars());

    var textDocumentParts = textDocument.GetParts() as List<Dictionary<string, object>>;

    foreach (var part in textDocumentParts)
    {
        foreach (var item in part.Keys)
        {
            Console.WriteLine(item + " " + part[item]);
        }
    }
}

Монада (Monad)

Паттерн «Монада» - это функциональный паттерн, который гарантирует, что каждая операция выполняется вне зависимости от успеха или неудачи предыдущей операции.

В качестве примера можно привести валидацию, где каждый шаг выполняется с уверенностью, что предыдущие шаги пройдены.

Реализация паттерна
public class Validator<T>
{
    private readonly T value;
    private readonly List<Exception> errors = new List<Exception>();

    public Validator(T value)
    {
        this.value = value;
    }

    public Validator<T> Validate(Predicate<T> validation, string message)
    {
        if (!validation(value))
        {
            errors.Add(new Exception(message));
        }

        return this;
    }

    public (bool, List<string>) Get()
    {
        if (errors.Any())
        {
            List<string> result = new List<string>();

            foreach (Exception e in errors)
            {
                result.Add(e.Message);
            }

            return (false, result);
        }

        return (true, new List<string>());
    }
}

public record User(string Name, string Surname, string Fathername) { }

private static void Main(string[] args)
{
    User fio = new("Иван", "Иванович", "Иванов");

    Validator<User> validator = 
        new Validator<User>(fio)
        .Validate(x => !string.IsNullOrEmpty(x.Name), "Name is null")
        .Validate(x => !string.IsNullOrEmpty(x.Surname), "Surname is null")
        .Validate(x => !string.IsNullOrEmpty(x.Fathername), "Fathername is null");

    (bool, List<string>) pair = validator.Get();

    Console.WriteLine(pair.Item1);
}

Мать объектов (Object Mother)

Паттерн «Мать объектов» - это порождающий паттерн, который используется для упрощения создания объектов с различными конфигурациями. Обычно он используется в контексте тестирования.

В качестве примера приведено создание аккаунта для физических и юридических лиц. В обоих случаях объекты аналогичны, но у них отличается часть свойств.

Реализация паттерна
public class Developer
{
    private string? name;
    private string? description;
    private bool isCompany;

    public void SetName(string name)
    {
        this.name = name;
    }

    public void SetDescription(string description)
    {
        this.description = description;
    }

    public void SetIsCompany(bool flag)
    {
        this.isCompany = flag;
    }
}

public static class DeveloperMother
{
    public static Developer CreatePerson(string name, string description)
    {
        Developer person = new();

        person.SetName(name);

        person.SetDescription(description);

        person.SetIsCompany(false);

        return person;
    }

    public static Developer CreateCompany(string name, string description)
    {
        Developer person = new();

        person.SetName(name);

        person.SetDescription(description);

        person.SetIsCompany(true);

        return person;
    }
}

private static void Main(string[] args)
{
    DeveloperMother.CreatePerson("Developer X", "Mobile apps");
    DeveloperMother.CreateCompany("VALVe", "CS:GO");
}

Пул объектов (Object Pool)

Паттерн «Пул объектов» - это порождающий паттерн, который управляет объектами, созданными раннее. Он хорошо подходит в случаях, когда создание нового объекта требует много ресурсов. Поэтому имеет смысл использовать повторно те объекты, которые уже есть.

Когда клиент запрашивает объект, то пул объектов пытается вернуть тот объект, который был создан раньше. В противном случае создаётся новый объект. Такой подход позволяет экономить ресурсы на инициализации и уничтожении объектов.

Реализация паттерна
public class ObjectPool<T>
{
    private readonly ConcurrentBag<T> _objects;
    private readonly Func<T> _objectGenerator;

    public ObjectPool(Func<T> objectGenerator)
    {
        this._objectGenerator = objectGenerator ?? throw new ArgumentNullException(nameof(objectGenerator));
        this._objects = new ConcurrentBag<T>();
    }

    public T Get()
    {
        return this._objects.TryTake(out T item) ? item : this._objectGenerator();
    }

    public void Return(T item)
    {
        this._objects.Add(item);
    }
}

public class ArrayObject
{
    public int[] Nums { get; set; }

    public ArrayObject()
    {
        this.Nums = new int[1000000];

        Random rand = new();

        for (int i = 0; i < this.Nums.Length; i++)
        {
            this.Nums[i] = rand.Next();
        }
    }

    public static double LOG(int value)
    {
        return Math.Log(value);
    }

    public static double SQRT(int value)
    {
        return Math.Sqrt(value);
    }
}

private static void Main(string[] args)
{
    CancellationTokenSource cancellationTokenSource = new();

    ObjectPool<ArrayObject> objectPool = new(() => new ArrayObject());

    Parallel.For(0, 1000000, (i, state) =>
    {
        ArrayObject example = objectPool.Get();

        Console.WriteLine(ArrayObject.SQRT(i));

        objectPool.Return(example);
        
        if (cancellationTokenSource.Token.IsCancellationRequested)
        {
            state.Stop();
        }
    });
}

Пошаговый строитель (Step Builder)

Паттерн «Пошаговый строитель» - это порождающий паттерн, который применяется для создание сложного объекта в несколько шагов. Он позволяет пользователю полностью создать объект без ошибок.

Исходный объект
public class TechniqueDB
{
    public int Id { get; set; }
    public string Date { get; set; }
    public string Image { get; set; }
    public string Title { get; set; }
    public string Subtitle { get; set; }
    public string Theme { get; set; }
    public string Author { get; set; }
    public string Algorithm { get; set; }
    public bool Removed { get; set; }

}

Реализация паттерна
public class TechniqueBuilder
{
    private readonly TechniqueDB techniqueDB;

    public TechniqueBuilder()
    {
        this.techniqueDB = new TechniqueDB();
    }

    public TechniqueBuilder SetIdentifier(int identifier)
    {
        this.techniqueDB.Id = identifier;
        return this;
    }

    public TechniqueBuilder SetDate(string date)
    {
        this.techniqueDB.Date = date;
        return this;
    }
    public TechniqueBuilder SetTitle(string title)
    {
        this.techniqueDB.Title = title;
        return this;
    }
    public TechniqueBuilder SetSubtitle(string subtitle)
    {
        this.techniqueDB.Subtitle = subtitle;
        return this;
    }

    public TechniqueBuilder SetTheme(string theme)
    {
        this.techniqueDB.Theme = theme;
        return this;
    }

    public TechniqueBuilder SetAuthor(string author)
    {
        this.techniqueDB.Author = author;
        return this;
    }

    public TechniqueBuilder SetAlgorithm(string algorithm)
    {
        this.techniqueDB.Algorithm = algorithm;
        return this;
    }

    public TechniqueBuilder SetImage(string image)
    {
        this.techniqueDB.Image = image;
        return this;
    }

    public TechniqueBuilder IsVisible
    {
        get
        {
            this.techniqueDB.Removed = false;
            return this;
        }
    }
    public TechniqueDB Build()
    {
        return this.techniqueDB;
    }
}

Применение паттерна
TechniqueBuilder builder = new();

TechniqueDB technique = 
     builder.SetIdentifier(count + 1)
    .SetTitle(this.Name)
    .SetSubtitle(this.Description)
    .SetTheme(this.Theme)
    .SetImage(this.Path)
    .SetAuthor(this.Author)
    .SetAlgorithm(this.Algorithm)
    .SetDate(date)
    .Build();

Продолжение в статье "Сто паттернов для разработки корпоративных программ. Часть 2.2".

Комментарии (57)


  1. AgentFire
    14.01.2024 11:21
    +5

    Мне кажется, что гораздо проще стать матёрым сеньором и создавать эти "паттерны" по ходу проектирования очередного компонента/сервиса/приложения, нежели заучивать этот безумный список.


    1. CSharpDeveloper2 Автор
      14.01.2024 11:21
      -3

      Возможно. Но лично у меня всего год опыта работы. Если ещё полгода назад я предпочитал писать всё по наитию, то потом пришёл к выводу, что на паттернах код получается лучше.


      1. lair
        14.01.2024 11:21
        +8

        Если ещё полгода назад я предпочитал писать всё по наитию, то потом пришёл к выводу, что на паттернах код получается лучше.

        Это нормально. Еще через несколько лет поймете, что надо не "писать на паттернах", а видеть паттерны в своих решениях.


        1. CSharpDeveloper2 Автор
          14.01.2024 11:21
          -1

          Не факт. Если вы не используете, то это не означает, что это правильно. Как минимум паттерн стратегия много где применялся.


          1. lair
            14.01.2024 11:21

            Если вы не используете, то это не означает, что это правильно.

            Мне кажется, вы не поняли, о чем я пишу. Я не говорю, что я не использую паттерны. Я говорю, что использование паттернов - не самоцель.

            Я, повторюсь, вообще считаю, что основная задача паттернов - не в том, чтобы по ним писать код.

            Как минимум паттерн стратегия много где применялся.

            Много применялся кем? В рамках чего? Зачем?

            Я вот не могу вспомнить, когда я в последний раз пользовался этим паттерном (хотя и помню, когда последний раз его видел, и совершенно не понимаю, зачем его там применили; код был плохой, и от паттерна лучше не стал).


            1. CSharpDeveloper2 Автор
              14.01.2024 11:21

              Безусловно. Паттерны не являются самоцелью. И большинстве случаев не приходится пользоваться. Но я вижу чужой код. И в некоторых случаях я бы использовал.


              1. lair
                14.01.2024 11:21
                +1

                Паттерны не являются самоцелью. И большинстве случаев не приходится пользоваться

                Тогда я не понимаю, как трактовать вашу фразу «на паттернах код получается лучше». Что вы ей хотели сказать?


                1. CSharpDeveloper2 Автор
                  14.01.2024 11:21

                  Имею в виду тот случай, когда можно написать код по-своему, но использование паттерна могло бы дать некоторые преимущества. То есть знать о существовании паттерна и использовать его в уместных случаях.


                  1. lair
                    14.01.2024 11:21
                    +1

                    В этом и проблема, что вы противопоставляете «по-своему» и «использование паттерна», хотя в реальности это не противоречащие друг другу вещи.

                    Когда я пишу код, как мне видится удобным, а потом кто-то приходит и говорит «да это же паттерн fluent interface» - что от этого поменялось в моем коде? Он перестал быть «по-моему»? Или он стал хуже? Или лучше?


  1. dopusteam
    14.01.2024 11:21
    +1

    Чем 'пошаговый строитель' отличается от паттерна 'строитель'?


    1. nronnie
      14.01.2024 11:21
      +5

      Тем же чем "Пул объектов" от "Приспособленца" и "Мать объектов" от фабрики. Названием :)


    1. CSharpDeveloper2 Автор
      14.01.2024 11:21
      -4

      По сути, это его модификация. А так всё то же самое.


      1. dopusteam
        14.01.2024 11:21
        +2

        В чем заключается модификация?


        1. CSharpDeveloper2 Автор
          14.01.2024 11:21
          -4

          Если я правильно понимаю, то в пошаговом строителе каждый метод возвращает экземпляр объекта в отличие от обычного. То есть потом в пошаговом мы можем написать что-то вроде new Builder().SetText("...").SetDescribtion("...").Build().


          1. dopusteam
            14.01.2024 11:21
            +1

            А откуда вы вообще нашли такой паттерн? Или вы сами его придумали?


            1. CSharpDeveloper2 Автор
              14.01.2024 11:21
              -1

              На просторах интернета. Есть много паттернов, по которым и на английском информации немного. А вот по банде четырёх информации действительно полно.


              1. dopusteam
                14.01.2024 11:21
                +2

                Поделитесь ссылкой?

                Я вот могу поделиться такой https://ru.m.wikipedia.org/wiki/Fluent_interface

                Кажется ваш пошаговый строитель - это обычный строитель + Fluent interface


                1. CSharpDeveloper2 Автор
                  14.01.2024 11:21
                  -2

                  Могу посоветовать Мартина Фаулера (Шаблоны корпоративных приложений). Где-то пдф находил и читал. Там не только паттерны, но и архитектура. Также могу порекомендовать этот сайт: https://java-design-patterns.com/patterns/


              1. lair
                14.01.2024 11:21
                +3

                Есть много паттернов, по которым и на английском информации немного.

                Так может тогда это и не паттерн?

                Смысл паттерна в том, что его опознают и одинаково понимают. Если это не работает, в паттерне нет смысла, это просто код.


  1. sshikov
    14.01.2024 11:21
    +8

    То что тут описано под название Монада, никакого отношения к монаде не имеет вообще. Продолжение фигни из предыдущего поста. Горшочек, не вари.


    1. CSharpDeveloper2 Автор
      14.01.2024 11:21
      -6

      Что имеет отношение к Монаде? Может, я что-то не знаю. Это так мило :)


      1. sshikov
        14.01.2024 11:21
        +5

        Но лично у меня всего год опыта работы. 

        Значит вы вообще ничего не знаете. Писать о паттернах с годом опыта вообще весьма самоуверенно. Получается на выходе как правило фигня, что мы и наблюдаем во втором посте.

        https://ru.wikipedia.org/wiki/Монада_(программирование)

        Вот монада, один из взглядов на нее (есть еще чисто математический взгляд). В упрощенном виде - потому что только на Хабре уже только ленивый не писал о монадах, и хорошо, и плохо, а главное - много.


        1. CSharpDeveloper2 Автор
          14.01.2024 11:21
          -6

          Ну да. В википедии описано иначе. Но я все равно продолжу писать. Предложение горшочку перестать варить отклонено.


          1. sshikov
            14.01.2024 11:21
            +1

            Ну как бы, то что у вас описано про монаду, обычно реализуется при помощи аппликативных функторов. Именно валидация. И это имеет смысл. И это даже похоже на монаду - но именно что похоже, а не является ей.


      1. sshikov
        14.01.2024 11:21
        +3

        Я бы даже так сказал - нет ничего плохого в том, что вы для себя пытаетесь разобраться в паттернах (хотя их польза на мой взгляд сильно преувеличена, для такого уровня опыта как у вас - и подавно). Но пытаться с годом опыта описать для других сто паттернов, с которыми вы никогда в жизни не сталкивались - бессмысленное занятие.

        Паттерн это типовое решение типовой задачи. У вас нет опыта решения типовых задач, для вас большинство задач пока новые. Я бы оценил число широко используемых паттернов в десяток, в лучшем случае.

        Причем - вот скажем с появлением в Java лямбд, т.е. по сути, безымянных функций, которые можно записать прямо в коде, некоторые паттерны в этом языке просто умерли за ненадобностью. Т.е. описывать сто паттернов в ситуации, когда язык развивается - это тоже ну такое...


        1. CSharpDeveloper2 Автор
          14.01.2024 11:21

          Да. Тут можно согласиться


          1. sshikov
            14.01.2024 11:21
            +1

            Ну да, суть в том чтобы выкинуть сто, которые все равно никто не применяет. И хорошо описать десяток.


        1. comradeleet
          14.01.2024 11:21

          Я бы оценил число широко используемых паттернов в десяток

          Можно увидеть вашу десятку? Какие наиболее часто встречаются в разработке у вас?


          1. lair
            14.01.2024 11:21
            +1

            Синглтон, фабрика и стратегия (в широком ее понимании). И адаптер еще. Вброс зависимостей, если считать его паттерном.

            И да, этот все специфично для ООП (кроме адаптера, адаптер универсален).


            1. comradeleet
              14.01.2024 11:21

              Удивительно, если бы я писал, то был бы такой же набор и даже в том же порядке, разве что, я бы ещё шаблоный метод добавил. Видимо от предметной области не сильно отличается используемость основных патернов


              1. lair
                14.01.2024 11:21

                Ничего удивительного - это все-таки самые базовые элементы, которые в той или иной мере нужны всем.


          1. sshikov
            14.01.2024 11:21

            Моя десятка может быть вам даже и не знакома - у меня там паттерны из EIP так называемых. Ну а помимо - фабрики, билдеры, это наверное уже процентов 90 будет.


  1. lair
    14.01.2024 11:21

    В этой статье рассматриваются такие дополнительные паттерны, которые не вошли в "Банду четырёх", но применяются в разработке приложений.

    Кто конкретно описал и ввел каждый из этих паттернов? Насколько они общеприняты?


  1. CSharpDeveloper2 Автор
    14.01.2024 11:21
    -6

    Я смотрю, в комментариях быдлохейтеров с предвзятым отношением развелось. Чтобы я не комментировал, сразу минус. И никаких комментариев.


    1. lair
      14.01.2024 11:21
      +2

      ...я вот вам написал пару комментариев, но отвечать вы не считаете нужным. Зато вот считать несогласных с вами людей быдлохейтерами - это легко, да.


      1. CSharpDeveloper2 Автор
        14.01.2024 11:21
        -4

        Я не считаю нормальным в случае несогласия переходить к унижениям и насмешкам как принято в обществе с "традиционными ценностями". Вы со своим президентом так пообщайтесь. И, по-моему, по вашим вопросам ответы и предыдущих комментариях были. Я бы не считал бы некоторые паттерны недействительными только от того, что реже встречаются. Какие-то Роберт Нистрем ввёл, какие-то - Мартин Фаулер, а по другим затрудняюсь сказать.


        1. lair
          14.01.2024 11:21
          +2

          Я не считаю нормальным в случае несогласия переходить к унижениям и насмешкам

          А я, вроде бы, и не делал ни того, ни другого. А вот "быдлохейтерами" оппонентов назвали вы.

          Вы со своим президентом так пообщайтесь.

          ...вы о чем вообще?

          Я бы не считал бы некоторые паттерны недействительными только от того, что реже встречаются.

          В чем, по-вашему, смысл паттерна? Чем паттерн отличается от просто решения в коде?

          Какие-то Роберт Нистрем ввёл, какие-то - Мартин Фаулер, а по другим затрудняюсь сказать.

          Если вы затрудняетесь сказать, то где вы этот паттерн взяли? Почему вы решили, что это паттерн?


          1. CSharpDeveloper2 Автор
            14.01.2024 11:21
            -1

            В вашем случае не было пренебрежений. Обычно я смотрю примеры чужого кода и выделяю те решения, которые считаю наиболее удачными.


            1. lair
              14.01.2024 11:21
              +1

              Решения, которые вам показались удачными в чужом коде - это не обязательно паттерн (и очень опасно их применять, не понимая контекста).

              В чем, по-вашему, смысл паттерна?


              1. CSharpDeveloper2 Автор
                14.01.2024 11:21

                Без контекста и нет смысла использовать. В моём понимании паттерн - это шаблон, который принято использовать в определённых случаях.


                1. lair
                  14.01.2024 11:21
                  +1

                  Без контекста и нет смысла использовать

                  А контекста вы в чужом коде можете и не знать. И это хорошо видно в вашей статье, где вы его и не приводите.

                  паттерн - это шаблон, который принято использовать в определённых случаях.

                  Вот отсюда и растет «код по паттерну», который приводит к куче паттернов без смысла.

                  Паттерны - это, в первую очередь, язык. Это возможность сказать коллеге «этот объект - синглтон», и мне не надо долго объяснять. Или «я взял визитор». Но чтобы это работало, у меня с коллегой должно быть общее понимание того, что такое синглтон (не «как реализуется», а «что такое»). А чтобы было общее понимание, паттерн должен быть общепринятым (хотя бы в данном сообществе). Отсюда и вытекает, что если конкретное решение паттерном считаете только вы - оно не паттерн для всех остальных, и в этом качестве неприменимо.


                  1. CSharpDeveloper2 Автор
                    14.01.2024 11:21

                    Из паттернов вижу банду четырёх, Мартина Фаулера и Роберта Нистрема как минимум. В обществе они по идее и являеются общепринятыми.


                    1. lair
                      14.01.2024 11:21
                      +1

                      Во-первых, про паттерны GoF и Фаулера я могу прочитать в первоисточнике, ваша статья никакой пользы не несет.

                      А во-вторых, вы не указываете, откуда взяты ваши паттерны, откуда и растет вопрос - а они точно общепринятые?

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


                      1. CSharpDeveloper2 Автор
                        14.01.2024 11:21

                        Когда начинал писать, была идея объяснить простым языком. Видать, получилось коряво и поверхностно. Лично я Мартина Фаулера начал понимать только после некоторых прочтений.


                      1. lair
                        14.01.2024 11:21
                        +1

                        Ну то есть вы считаете, что (а) поняли достаточно, чтобы объяснять другим, и (б) считаете, что другие не могут понять то же самое сами, хотя у вас, если я правильно понимаю, год опыта работы?

                        Как вы наверное догадались из комментариев, ваши читатели оказались не согласны с вашей оценкой. Лично я вот считаю, что вы пока недостаточно понимаете паттерны, чтобы кому-то их объяснять.


                      1. CSharpDeveloper2 Автор
                        14.01.2024 11:21

                        Быть может. Да и по-хорошему на каждый паттерн отдельную статью надо, а иначе не будет глубины.


                      1. lair
                        14.01.2024 11:21
                        +1

                        Нет, не надо (вам) на каждый паттерн отдельную статью, у вас недостаточно опыта, чтобы их наполнить.

                        Есть же первоисточники, вам есть, что нового сказать по сравнению с ними?


                      1. CSharpDeveloper2 Автор
                        14.01.2024 11:21
                        +1

                        Скорее всего нет


        1. lair
          14.01.2024 11:21

          Какие-то Роберт Нистрем ввёл

          Это который «Паттерны программирования игр» (никакой другой книги за этим именем я не нашел)?


          1. CSharpDeveloper2 Автор
            14.01.2024 11:21

            Да. Но лично я разработкой игр не занимаюсь. Вряд ли потребуется


            1. lair
              14.01.2024 11:21

              И вас не смущает, что вы ссылаетесь на паттерны, введенные этим человеком, в статье «паттерны для разработки корпоративных приложений»? А как же тот самый контекст?


              1. CSharpDeveloper2 Автор
                14.01.2024 11:21

                Роберта Нистрема ещё не описывал. По крайней мере в этих двух статьях. Да и не стоит.


                1. lair
                  14.01.2024 11:21

                  Тогда зачем вы вообще его поминали в контексте вопроса «откуда ваши паттерны»?

                  Забавно, конечно. Паттерны предлагались, в числе прочего, как способ структурировать знание, а вы их превращаете в анонимные советы, девальвируя их обратно.


                  1. CSharpDeveloper2 Автор
                    14.01.2024 11:21

                    А у меня сложилось впечатление, что не только Банда четырёх и Мартин Фаулер являются популярными.


                    1. lair
                      14.01.2024 11:21

                      Популярность - не то же самое, что применимость.

                      Я же вас постоянно спрашиваю, откуда вы взяли конкретный паттерн.


                      1. CSharpDeveloper2 Автор
                        14.01.2024 11:21

                        Многие паттерны попались тут: https://java-design-patterns.com/patterns/. Считаю, что в некоторых случаях они применимы.


                      1. lair
                        14.01.2024 11:21

                        Некоторые из них в некоторых конкретных случаях применимы, да. Я, скажем, туда вообще не пойду, потому что они явно декларируют ограничение по языку.

                        Но этот ресурс - это каталог, там есть ссылки на первоисточники (по которым вы, похоже, поленились пройти), и объяснения там все равно лучше и детальнее ваших (включая рекомендации по применимости).

                        Что возвращает меня к мысли о том, что пользы от вашей статьи чрезвычайно мало - все равно надо читать первоисточники, а вы их не указываете.