Установка значений по умолчанию для свойств объекта в AS3 - PullRequest
0 голосов
/ 28 декабря 2010

Я новичок в ActionScript, поэтому, пожалуйста, потерпите меня. Ниже приведена функция, и мне интересно, как установить значения свойств по умолчанию для объектов, которые создаются в цикле.

В приведенном ниже примере эти свойства одинаковы для каждого объекта, созданного в цикле: titleTextField.selectable, titleTextField.wordWrap, titleTextField.x

Если вы извлечете эти свойства из цикла, они будут нулевыми, потому что объекты TextField не были созданы, но кажется глупым каждый раз устанавливать их. Как правильно это сделать. Спасибо!

var titleTextFormat:TextFormat = new TextFormat();   
    titleTextFormat.size = 10;  
    titleTextFormat.font = "Arial";
    titleTextFormat.color = 0xfff200;

for (var i=0; i<arrThumbPicList.length; i++) {

    var yPos = 55 * i

    var titleTextField:TextField = new TextField();  
        titleTextField.selectable = false;
        titleTextField.wordWrap = true;
        titleTextField.text = arrThumbTitles[i];
        titleTextField.x = 106;
        titleTextField.y = 331 + yPos;

    container.addChild(titleTextField);
    titleTextField.setTextFormat(titleTextFormat);

}

Ответы [ 4 ]

3 голосов
/ 29 декабря 2010

Здесь в основном три варианта.

  1. Вы можете создать собственный класс, который будет действовать как прокси для TextFormat.Например, TextFormatProxy, который может создать TextFormat в своем конструкторе и установить каждое из ваших значений по умолчанию.См. эту ссылку или google "Шаблон прокси AS3".
  2. Вы можете написать собственный класс, который расширяет TextFormat и аналогично, установить эти значения по умолчанию в конструкторе или в функции по вашему выбору..
  3. Вы можете использовать небольшую вспомогательную функцию, подобную этой

package {
    import flash.display.Sprite;

    public class DefaultProperties extends Sprite{

        public var s:Sprite;

        public function DefaultProperties() {
            s = new Sprite();
            s.graphics.beginFill(0x00ff00, 1);
            s.graphics.drawRect(0, 0, 100, 100);
            s.graphics.endFill();
            this.setDefaults(s, {x:100, y:200, scaleX:.5});
            this.addChild(s);
       }

       function setDefaults($obj:*, $properties:Object):void {
           for (var i in $properties) {
               $obj[i] = $properties[i];
           }
       }
    }
}
2 голосов
/ 29 декабря 2010

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

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

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

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

public interface FormatFactory
{
    function getInstance():TextFormat;
}

public class TitleFormatFactory implements FormatFactory
{
    public function getInstance():TextFormat
    {
        var format:TextFormat = new TextFormat();   
            format.size = 10;  
            format.font = "Arial";
            format.color = 0xfff200;

        return format;
    }
}

Фабрики могут или не могут быть параметризованы:

public interface TextFieldFactory
{
    function getInstance(text:String, position:Point, format:TextFormat):TextField;
}

public class TitleFactory implements TextFieldFactory
{
    public function getInstance(text:String, position:Point, format:TextFormat):TextField
    {
        var title:TextField = new TextField();  
            title.selectable = false;
            title.wordWrap = true;
            title.text = text;
            title.x = position.x;
            title.y = position.y;
            title.setTextFormat(format);

        return title;
    }
}

Наконец, вот как вы должны использовать код:

var formatFactory:FormatFactory = new TitleFormatFactory();
var titleFactory:TextFieldFactory = new TitleFactory();

var format:TextFormat = formatFactory.getInstance();

for (var i = 0; i < arrThumbPicList.length; i++)
{
    var position:Point = new Point(106, 331 + 55 * i);
    var title:TextField = titleFactory.getInstance(text, position, format);

    container.addChild(title);
}

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

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

0 голосов
/ 29 декабря 2010

Твой код в порядке для меня.Просто и эффективно.У вас есть только 3 фиксированных параметра, для меня нет необходимости делать больше:

titleTextField.selectable = false;
titleTextField.wordWrap = true;
titleTextField.x = 106;

В отличие от другого ответа, я бы сделал вспомогательную функцию для получения текстового поля со всеми фиксированными параметрами (я бы сделал это ТОЛЬКОесли бы было много вещей, чтобы сделать).

function createMyContextTextField():TextField{
    textfield:TextField = new textField();
    textfield.selectable = false;
    textfield.wordWrap = true;
    textfield.x = 106;
    return textfield;
}
0 голосов
/ 29 декабря 2010

Если бы я подошел к той же проблеме, я бы использовал ту же, что и вы, только потому, что создание новой структуры данных было бы ненужным.Альтернативой может быть создание функции, которая принимает текстовое поле в качестве параметра:

for (var i=0; i<arrThumbPicList.length; i++) {
     var titleTextField:TextField = new TextField();
     setProperties(titleTextField,i);
}


function setProperties(txt:TextField,offset:int){
       var yPos = 55 * offset;
       txt.selectable = false;
       txt.wordWrap = true;
       txt.text = arrThumbTitles[offset];
       txt.x = 106;
       txt.y = 331 + yPos;

       container.addChild(titleTextField);
       titleTextField.setTextFormat(titleTextFormat);

       i++;
  }

Хотя я бы, вероятно, следовал тому, что вы опубликовали, если вы не добавляете элементы из нескольких для циклов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...