Uniform Access Principle

Днес прочетох за нещо, наречено Meyer’s Uniform Access Principle. Това е един много интересен прицип касаещ ООП езиците. Гласи горе-долу следното:

Атрибутите на един обект трябва да се достъпват чрез нотация, която не позволява да се различи дали те са имплементирани чрез запис или чрез изчисление.

Иначе казано, line.length не трябва да издава дали става въпрос за поле или метод, изчисляващ разстоянието между двата края. Това е много хубава идея, понеже промотира любимите ми думички – абстракция и енкапсулация. Та, замислих се доколко това важи в езиците, които ползвам.

Ruby

Тук положението е най-добре. В Ruby дори няма концепцията за публично поле – точката служи единствено за извикване на метод. Но комбинацията незадължителните скоби и attr/attr_accesor имплементира този принцип естествено.

class Line
  attr :start, true
  attr :end, true

  def length
    start.distance_to end
  end
end

line = Line.new
line.start = Point.new(0, 0)
line.end = Point.new(3, 4)
puts line.length

Python

При питона положението е по-средно. Има ясно разделение между функции и полета. Границата между тях може да бъде изтрита като се ползва property, но това вкарва синтактичен шум за да станат нещата чисто.

Друг проблем идва, от това че length може да бъде или само поле или само метод. За да следвате принципа трябва да вземете решение дали ще се обръщате като line.length или line.length(). Докато първото е в духа на UAP, то ви води към едно коварно усложнение. В повечето класове ще има доста методи, които не могат или не е логично да се реализират като property. Така често потребителите на вашия код ще се чудят „Тук да слагам ли скоби или не?“. Това ще създаде повече усложнения, отколкото удобства.

Java

Стандарта в Java повелява да не показваме полетата публично и да скриваме за двойка методи getFoo/setFoo. Това донякъде скрива дали става въпрос за поле или изчисление, но само частично – думичките get и set издават, че става въпрос за property. Отвъд това ми се струва валидна имплементация. Предимството е, че 99% от Java кода ще уважава този стандарт. Недостатъка са двата шаблонни метода за всяко property, създаващи единствено шум.

Някъде видях идеята вместо getSize()/setSize(5) да се ползва size()/size(5). Това ще е съвсем в духа на UAP, но в остър разрез със стандартите на Java.

Накратко

Ruby поддържа този принцип отръки. Да отворим бира на Matz. Java и Python могат да го добутат, но според мен това ще доведе единствено до усложнения за програмиста.

Вашият коментар

Вашият имейл адрес няма да бъде публикуван.