ООП. Инкапсуляция и сокрытие данных

      Комментарии к записи ООП. Инкапсуляция и сокрытие данных отключены

В этой теме 0 ответов, 1 участник, последнее обновление  Васильев Владимир Сергеевич 3 нед., 6 дн. назад.

  • Автор
    Сообщения
  • #4023

    Этот вопрос кому-то покажется интересным, кому-то забавным, кому-то ни о чём.
    В программировании, как и в других науках, существует терминология. Каждый термин описывает определённое явление. И тот, кто претендует называть себя специалистом в данной области, как бы хочешь не хочешь, а должен этой терминологией владеть. Поэтому все выпады и реплики на предмет “кому нужны эти пустые формулировки, я же программист, а не преподаватель”, можете оставить при себе. Звучат они не в вашу пользу, и характеризуют вас как не специалиста.

    Есть в английском языке прекрасная фраза “It’s a must”. Которой на русском языке я боюсь не найти таких же лаконичных аналогов. Но примерно звучит так: “НАДО”.
    Так вот, здесь и сейчас мы поговорим как раз о том, что многим не кажется простым вопросом. В чём разница между инкапсуляцией и сокрытием данных.

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

    Или С++, который хоть и считается объектно-ориентированным, всё же вполне допускает наличие переменных, хранящихся вне классов или структур.
    Когда я думаю, как это выглядит в реальном мире, когда законы инкапсуляции нарушаются, в силу каких-то причин, почему-то очень живо представляется бабушка, сидящая на диванчике, а рядом с ней на тумбочке – её вставные челюсти, парик, очки и протез левой ноги у дивана. Жуткая картина.
    А ещё представляется, как я прихожу в ресторан, заказываю утку под вишнёвым соусом, а повар с сияющей улыбкой прямо на моих глазах рубит ей голову, потрошит и кидает в кипяток. Тоже мало приятного.

    В первом случае – хотелось бы какой-то целостности объекта, во втором – поменьше деталей о процессе.

    Это и есть то, на чём базируются инкапсуляция и сокрытие данных. Детали реализации и данные упакованы в объект, и объект является их полноправным владельцем.

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

    И вот это уже называется сокрытие данных (data hiding). Сокрытие данных достигается посредством модификаторов доступа (в С# – это модификаторы private, public, protected, protected internal), каждый из которых определяет свой уровень доступности членов типа.

    Рассмотрим пример. Здесь определяется класс Person, который инкапсулирует 2 приватных поля – имя (name) и возраст (age). Модификатор private в языке C# означает, что доступ к помеченному полю возможен только в пределах самого класса, а не через экземпляр и не для наследников. Контроль доступа на чтение и запись предоставляют свойства Name и Age. В них проверяется назначаемые величины, на диапазон и формат.

    class Person
    {
       private string name;
       private int age;
     
       public string Name
       {
       get { return name; }
       set
       {
            if (value.Length >=2 && value.Length <= 25)
            {
               name = value;
            }
            else
            {
                throw new FormatException("the length of name can't be less than 2 or longer than 25");
            }
         }
      }
     
       public int Age
       {
          get { return age; }
          set
          {
             if (value > 1 && value < 120)
             {
                 age = value;
             }
             else
             {
                 throw new ArgumentOutOfRangeException();
             }
          }
     
       }
     
        public override string ToString()
       {
          return String.Format("name - {0}, age - {1}", Name, Age);
       }
     }
     
    class Program
    {
       static void Main()
       {
          Person person = new Person() { Name = "John", Age = 147 };
         Console.WriteLine(person);
       }
    }

    Можно сказать, что сокрытие – это одна из задач инкапсуляции. Но само по себе сокрытие данных инкапсуляцией не является.
    Также сказать, что инкапсуляция – это сокрытие данных, тоже было бы неверно. Потому что её задачи выходят за рамки сокрытия.

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

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

Для ответа в этой теме необходимо авторизоваться.