我是一个动作新手所以请耐心等待我。下面是一个函数,我很好奇如何为循环中创建的对象设置默认属性值。
在下面的示例中,这些属性对于在循环中创建的每个对象都是相同的:titleTextField.selectable,titleTextField.wordWrap,titleTextField.x
如果将这些属性拉出循环,它们将为null,因为尚未创建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);
}
答案 0 :(得分: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];
}
}
}
}
答案 1 :(得分:2)
在不知道周围代码的情况下,我建议将任何构造逻辑放在工厂对象中。如果这太过分了,那么我会说你的代码没问题。将它拉出循环并进入辅助方法实际上只是添加了另一层间接,这不仅难以读取,而且由于您在堆栈上引入了另一个方法调用,因此效率也较低。
如果您的类对事物的创建方式并不感兴趣,而只需要一个或多个实例,那么使用工厂对象是很好的。这样,工厂负责创建对象,并且您可以很好地分离关注点。
我不建议创建仅用于设置实例属性的代理结构。我认为这是一种反模式,因为它有利于继承而不是组合,它只是为了代码重用的目的。但这样做意味着你将自己锁定在特定的实现上,这可能不是你想要的。仅仅因为你的textfield 具有某个值,并不意味着 是一个不同的类型。
这是您的代码在使用工厂模式时的外观,首先是格式工厂:
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);
}
除了可读性之外,一个巨大的好处是你现在可以交换工厂的实现,从而改变你正在使用的组件类型,而不必改变你的实际逻辑。您所要做的就是更改对工厂的引用。
此外,通过分离问题,您可以更轻松地专注于代码的某个方面,从而减少引入错误的风险,如果您仍然这样做,那么通常更容易发现和修复。此外,当您分离关注点,更重要的是,从业务逻辑中创建逻辑时,单元测试代码要容易得多。
答案 2 :(得分:0)
如果我接近同样的问题,我会使用与你发布的相同的问题,因为制作新的数据结构是不必要的。另一种方法是创建一个接受文本框作为参数的函数:
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++;
}
虽然我可能会按照您发布的方式进行操作,除非您从多个for循环中添加内容。
答案 3 :(得分:0)
您的代码对我来说没问题。简单有效。你只有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;
}