?

Log in

No account? Create an account

Previous Entry | Next Entry

grafiti
или "Как не задавать ненужных вопросов"

В предыдущей лекции я объяснила как надо программировать )

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

Это правило кстати постоянно нарушаецца, отсюда типичные ошибки программы, когда прога допустим пытаецца стереть стертый файл, т.е. "войти в одну и ту же реку дважды" или наоборот, войти в реку которой еще нет (т.е. прочитать несуществующий файл).

Наш пример с дверью, которая может быть или откыта или закрыта, но не открыта или закрыта одновременно, всем прекрасен, кроме одного. Он не учитывает "контекста", в котором одно и то же состояние может означать разные вещи.

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

В каком состоянии находицца дверь?

Для "простого прохожего" она закрыта, для миня открыта, если же я ее запру на пимпочку, для миня она закрыта, а для адмимистратора все равно открыта.

Это означает, что для моделирования такого поведения двери нужно объяснить следующие состояния:

ОП (открыта для прохожих)
ЗП (закрыта для прохожих)
ОГ (открыта для гостя)
ЗГ (закрыта для гостя)
ОА (открыта для администратора)
ЗА (закрыта для администратора)

Это не очень хорошо, так как получаецца много состояний. Представьте, что состояний дверей было бы не 2 а 100, и разных типов юзеров было не 3 а тоже 100. Получаецца 100 х 100 == 10000. Ужос.

Тогда так. Представим, что есть два состояния (О и З) и три "контекста" (П, Г и А). Причем эти три "контекста" иерархически отличаюцца друг от друга по уровню привилегий. Можно это выразить значениями 3 (самый низкий уровень, для прохожих), 2 (средний уровень для гостя) и 1 уровень (для "модера").

Итак мы получаем, что дверь может иметь разную степень открытости:

О (1,2,3)
З (2,  3)


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

При этом внутрення логика что О может перейти токо в З а З токо в О остаецца в силе для всех. При этом каждый пользователь может менять уровень закрытости на меньший, если такой существует, но не на больший. Например, прохожий не может запереть миня снаружи, но я могу запереть дверь для прохожего изнутри, в то время как для модера дверь все равно будет открытой.

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

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

Обозначим дни недели символами ПО,ВТ,СР,ЧЕ,ПЯ,СУ,ВО а юзеров числами 1 (модер), 2 (гость), 3 (прохожий), 4 (воскресный модер):

О (ПО: (1,2), ВТ: (1,2), СР: (1,2,3), ЧЕ: (1,2), ПЯ: (1,2), СУ: (4,2) ВО: (4,2)
З (ПО: (3,2), ВТ: (3,2), СР: (2,3),   ЧЕ: (3,2), ПЯ: (3,2), СУ: (3,2) ВО: (3,2)


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

При каждом повороте ключа в двери прога генерирует "свой ключ", состоящий из хэш-значения, в зависимости от уровня юзера, дня недели и в какую сторону они пытаюцца открыть дверь, допустим (в упрощенном виде) такой:

ОСР3

Под этим ключом храницца команда с одной функцией: "ПУЩЯТЬ С ПРОВЕРКОЙ" (посетителям в среду "можно", но осторожно)

Ключ ОПО4 хранит функцию "НЕ ПУЩЯТЬ С ЗАПИСЬЮ В ЛИЧНОЕ ДЕЛО", так как воскресный модер в понедельник модерировать не может, а что он там пытаецца разнюхать мы выясним.

Ключ ОПО2 хранит функцию "ПУЩАТЬ ВЕЖЛИВО" так как это гость и т.д.

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

if (isMonday())
  if (isVosrkesnyiModer())
     if (Open())


и т.д.

Ибо многоступенчатые ифы ужасны. Даже одноступенчатые ифы ужасны, ибо зачем задавать бессмысленный вопрос, ответ на который прога и так уже знает до того, как ее спросили?

Кароче, делайте как я, ваш код будет "пуленепробиваемым" :) а ифы путь аутсорсники делают.


Comments

( 3 comments — Leave a comment )
nasha_sasha wrote:
23rd May, 2011 20:27 (UTC)
Хихи:)
meggen wrote:
28th May, 2011 00:32 (UTC)
Саш...как в тебе это все помещается? Я тут только мажорные гаммы освоила-в смысле принцип поняла и детенышу объяснила, а они интервалы начали проходить. Тут уж я сказала: " Дальше -сама!"Я ей только ассоцации придумала, чтобы запомнить...прима-секунда-терция и кварта....(это песенкой) и чувствую, меня на большее не хватает, а ты и математику можешь разложить...!
( 3 comments — Leave a comment )