Является ли использование методов получения свойств для инициализации (чтобы избежать вызова методов в указанном порядке c) плохой практикой? - PullRequest
0 голосов
/ 21 февраля 2020

Предположим, у меня есть класс, который предоставляет некоторые данные для моего приложения. Первоначально данные поступают из базы данных, и я предоставляю их с помощью некоторых методов, которые обрабатывают всю базу данных и представляют результат в виде пригодного для использования класса вместо необработанного результата запроса. Этот класс должен выполнить некоторую настройку (не сложную), чтобы убедиться, что любой вызванный метод может использовать базу данных (например, подключиться к базе данных, убедиться, что она содержит некоторую критическую информацию, например, c). Итак, если бы я поместил его в метод (скажем, метод Init (), который бы обрабатывал проверку базы данных, подключение к ней, проверку того, что она содержит информацию), я должен был бы убедиться, что этот метод вызывается раньше любой другой метод. Итак, я обычно нахожу, что вместо того, чтобы делать это:

public class DataProvider
{
    private SqlController controller;

    public void Init()
    {
        controller = new SqlController();
        controller.Init();
        controller.ConnectToDataBase();
        CheckForCriticalInfoInDatabase();
    }

    public Data GetData()
    {
        // get data from database (not actually going to use raw queries like that, just an example)
        var queryResult = sqlController.RunQuery("SELECT something FROM SOME_TABLE");
        // and present it as usable class
        Data usefulData = QueryResultToUsefulData(queryResult);
        return usefulData; 
    }

    ...
}

, а затем всегда проверять, чтобы я вызывал Init () перед GetData (), я делаю что-то вроде

    private SqlController _controller;

    private SqlController controller
    {
        get
        {
            if (_controller == null)
            {
                _controller = new SqlController();
                _controller.Init();
                _controller.ConnectToDataBase();
                CheckForCriticalInfoInDatabase();
            }
            return controller;
        }
    }

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

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

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

1 Ответ

0 голосов
/ 21 февраля 2020

Как сказал @madreflection в комментариях ОП, используйте метод для всего, что может быть медленным. Геттеры и сеттеры должны быть просто быстрыми способами получения и установки значения.

Соединения с БД могут быть медленными или не могут соединиться, поэтому у вас могут быть настройки перехватчиков, чтобы попробовать разные способы соединения et c.

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

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

...