Статьи

AS3 101: быстрый совет — эффективно используйте модификаторы доступа

При объявлении свойств и методов вы можете выбрать один из четырех модификаторов доступа: private , protected , internal и public . Как вы знаете, какой использовать?

Прежде чем я отвечу на этот вопрос, давайте рассмотрим, почему мы беспокоимся о частном (и защищенном и внутреннем), а не просто обнародуем все? Ну, есть небольшая вещь, называемая инкапсуляция в объектно-ориентированном программировании . За этим стоит идея «черного ящика» дизайна классов. Вам не нужно знать, как работает коробка, чтобы сделать свою работу. Возьмите машину, например. Вам не нужно знать в первую очередь, как работает двигатель, чтобы вы сидели на месте водителя и заставляли автомобиль двигаться. Внутренняя работа автомобиля заключена в капсулу, и все, что вам нужно знать, это то, что вы можете делать снаружи (например, нажимать на педали и поворачивать колесо; кого волнует, как колеса поворачиваются при нажатии на газ, просто так пока они делают ?).

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


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

Например, представьте класс, который имеет метод » foo() «. Если мы начнем делать foo() публичной, тогда любой другой объект может вызвать его. Теперь мы решили, что по какой-то причине foo() действительно должен вызываться только при контролируемых обстоятельствах, поэтому мы хотим сделать его приватным. В момент изменения «public» на «private» может быть любое количество других объектов, уже вызывающих foo() , потому что это public. Как только мы сделаем это, мы рискуем сломать существующий код.

С другой стороны, предположим, что был метод » bar() «, который мы изначально написали как private, и единственное место, где мы можем вызвать bar() находится внутри самого объекта. Но с тех пор мы решили, что bar() действительно является сердцем и душой этого объекта, и мы могли бы действительно сделать вещи замечательными, обнародовав его. По мере внесения изменений мы знаем, что единственный код, который мог ранее вызвать bar() все еще сможет вызывать его после изменения.


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

Почему? Короче говоря, потому что вы не хотите, чтобы какой-то другой код изменял значение ваших свойств, не зная об этом. Это не параноик, «Большой брат всегда смотрит» подход к программированию. Но речь идет о контроле.

Это не означает, что никогда не должно быть публичного доступа к стоимости. Вместо этого стоит сказать, что мы должны контролировать публичный доступ к стоимости. Подумайте: что, если у вашего объекта есть свойство String , содержащее одно из трех возможных значений, и объект ведет себя немного по-разному в зависимости от состояния этого свойства? Например:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
public var state:String;
public function foo():void {
    switch (state) {
        case «A»:
            trace(«foo — a»);
            break;
        case «B»:
            trace(«foo — b»);
            break;
        case «C»:
            trace(«foo — c»);
            break;
    }
}

И в использовании это:

1
2
3
4
myObject.state = «A»;
myObject.foo() // traces «foo — a»;
myObject.state = «B»;
myObject.foo() // traces «foo — b»;

Теперь, если вам случится написать:

1
2
myObject.state = «a»;
myObject.foo() // nothing happens!

Тогда state никогда не совпадает. Конечно, вы можете добавить значение по умолчанию к оператору switch и даже выполнить toUppercase() для свойства state при его оценке, но было бы лучше просто проверить значение по мере его установки.

Написание открытого сеттера для свойства позволяет вам изучить входящее значение и соответственно отреагировать.

1
2
3
4
5
6
7
8
private var _state:String;
public function set state(value:String):void {
    if (value == «A» || value == «B» || value == «C») {
        _state == value;
    } else {
        throw new Error(«Invalid value set for state: » + value);
    }
}

Конечно, вы можете справиться с этим так, как вам хочется, и в этом вся прелесть частной собственности в сочетании с публичными сеттерами и геттерами.

И, чтобы вернуться к первому правилу, это «безопасное» изменение, когда у вас есть частное свойство, для которого вы позже добавите публичные установщики и получатели.

Смотрите мой быстрый совет по сеттерам и геттерам для получения дополнительной информации.