Использовать ли частные или публичные методы

По мере того, как я продолжаю совершенствовать свою игру в палач на C#, чтобы помочь мне выучить язык и мыслить как программист, в нем есть методы, которые, я думаю, должны быть в отдельных классах. Прямо сейчас весь код находится в классе Form (Windows Form). Это делает вызов необходимых методов действительно простым, поскольку мне нужно только использовать имя метода и использовать необходимые параметры. И, поскольку это всего лишь простая игра палача, это может быть лучшим способом сделать это. Я не знаю.

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

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

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

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

Рассматриваемый код является следующим (метод, который читает файл, формирует массив, перемешивает и т. Д.):

private void ReadFile(StringBuilder hintlength, string[] wordlist, string lettercountpath) 
{
  string fileContent = File.ReadAllText(lettercountpath); //Read file
  string[] array = fileContent.Split((string[]null, StringSplitOptions.RemoveEmptyEntries); //Form array

  Random rand = new Random(); 

  for (int i = 0; i < array.Length; i++) // Shuffle algorithm 
  {
    int randIndex = rand.Next(i, array.Lenth);
    string temp = array[randIndex];
    array[randIndex] = array[i];
    array[i] = temp;
  }

  for (int i = 0; i < 10; i++0)  //Assigns shuffled array into wordlist array
    wordlist[] = array[i];

  if (j > 9) //Checks counter to see how many times it's been clicked
     j =0;

  Start.Enabled = false;
  NewWord.Enabled = false;

  WordSelection(hint length, wordlist); // Calls WordSelection method 

  radioButton1.Enabled = false;
  radioButton2.Enabled = false;
  radiobutton3.Enabled = false;

  if (remainderWords == 1) // Checks remaining words counter
     remainderWords = 10;
}

2 ответа

Решение

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

  • Если метод или поле представляет или делает что-то, что имеет отношение к тому, как класс выполняет свою работу, но не к тому, как пользователи класса видят, что он делает, отметьте член как закрытый. Причудливое название для этого - "детали реализации": вы не хотите, чтобы они были представлены, чтобы вы могли изменить их позже.
  • Если метод или поле необходимы для того, что класс делает для своих пользователей, сделайте этот член общедоступным: в противном случае никто не сможет использовать этот член, что сделает весь класс бесполезным.
  • Если ваш класс предназначен для наследования, а метод или поле подготовлены для исключительного использования этим классом и его подклассами, сделайте этот метод защищенным.
  • Если метод или поле являются деталями реализации, которые должны быть видны другим классам в той же сборке, сделайте член internal, Вы можете смешивать internal а также protectedдальнейшее ограничение доступа к производным классам внутри той же сборки.

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

Существует концепция наличия класса для каждой ответственности. Для вашей программы Hangman вам нужно случайное слово, которое вы читаете из файла. Это хорошее время для создания нового класса: класса, который читает файл слов и дает вам случайное слово.

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

public class HangmanWordProvider
{
    private string[] _words;

    public HangmanWordProvider(string inputfile) {
        // code to read file into _words variable here
    }

    public string GetRandomWord()
    {
        // code to return a random word from the collection
    }
}

Затем вы создадите новый экземпляр поставщика слов для использования во время игры. Ваш главный HangmanGame теперь больше не нужно беспокоиться о чтении файла слов или получении случайного слова из коллекции. Вы просто позвоните wordprovider.GetRandomWord() и знаю, что вы получите необходимые данные. Это разделение интересов.

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

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

private Части в классе предназначены для сокрытия реализации частей, о которых другие классы не должны знать. В вашем случае игре не нужно знать о том, как хранится список слов, откуда он загружается или каким способом вы используете случайный результат. Нужно только знать, как можно получить одно случайное слово.

Другие вопросы по тегам