Есть ли название для этой техники, и это кодовый запах? - PullRequest
2 голосов
/ 17 марта 2020

Ранее я видел код, подобный следующему, в результате чего к объекту добавляется своего рода «метод доступа к расширению». Метод расширения будет отображаться в intellisense как только один метод, но при выборе этого параметра intellisense будет отображаться со всеми методами, определенными в классе «manager». Кажется, это хороший способ организовать набор аналогичных функциональных возможностей и очистить основной смысл первичного объекта.

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

public class StringManager
{
    public StringManager(String value)
    {
        Value = value;
    }

    private String Value { get; set; }

    public int GetTwiceLength()
    {
         return Value.Length * 2;
    }

    public decimal GetHalfLength()
    {
         return Value.Length / 2;
    }
}

public static class StringExtensions
{
    public static StringManager Operations(this String value)
    {
        return new StringManager(value);
    }
}

приведенный выше код будет использоваться следующим образом:

var myString = "the string";
var twiceLength= myString.Operations().GetTwiceLength();

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

1 Ответ

0 голосов
/ 09 мая 2020

Это похоже на шаблон адаптера .

Адаптер - это структурный шаблон проектирования, который позволяет объектам с несовместимыми интерфейсами взаимодействовать. - [https://refactoring.guru/design-patterns/adapter]

Позвольте мне объяснить, почему я думаю, что это применимо здесь:

Методы расширения в C# являются просто обычными состояниями c методы с небольшим количеством сахара syntacti c. Ключевое слово this для первого параметра функции позволяет вам вызывать его , как если бы это был метод экземпляра для этого типа. Но вы также можете назвать его как обычный метод stati c:

StringExtensions.Operations("your string").CallMethtod();

Рассматривая реализацию Operations:

public static StringManager Operations(this String value)
{
    return new StringManager(value);
}

Мы можем видеть, что это обычный старый stati c фабричный метод , который возвращает экземпляр вашего класса Manager (= адаптер). Это эквивалентно непосредственному созданию экземпляра apapter (но на самом деле это выгодно, поскольку оно скрывает «как» создавать новые экземпляры. Например, вы можете объединять и повторно использовать существующие экземпляры):

new StringManager("your string").CallMethod();

Ваш класс Manager адаптирует string type / interface для совместимости с другим интерфейсом, предоставляя все ваши «методы управления» вместо оригинальных строковых методов. Чтобы сделать «адаптер» явно видимым, полезно использовать промежуточную переменную (в демонстрационных целях):

var originalString = "your string"; var adapStString = new StringManager (originalString); adapStString.CallMethod ();

Это запах кода? Я так не думаю, не обязательно. Вы только адаптируете интерфейс одного класса к другому интерфейсу (строковый интерфейс к интерфейсу StringManager). Можно утверждать, что «Менеджер» не должен использоваться в именах классов, потому что он не добавляет никакого полезного контекста и может в основном означать что угодно. Рано или поздно все ваши классы станут своего рода менеджером, сервисом или менеджером сервиса.

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

...