AS3如何从任何地方访问类的实例?

时间:2011-06-15 23:01:16

标签: actionscript-3 frameworks

我目前通过构造函数将对模型的引用传递给我的简单mvc模式中需要它的任何类,这有时会在它开始变深时变得烦人。

LoadMax等类如何允许您从任何地方简单地导入类,并执行addChild(LoaderMax.getContent("bg"));之类的操作?复制这一点肯定是让我的模型工作的好方法,而没有大框架的复杂性?

4 个答案:

答案 0 :(得分:3)

静态是你的朋友

正如之前的答案所指出的那样,TweenLite/Max等会大量使用static成员来完成工作。例如,这与Math类完全相同,并且可以是非常方便的设计模式。您可以全局访问该类,这肯定可以缓解通过深层嵌套类访问变量的问题。

静力学是敌人

但是,静力学会带来一些问题。最重要的是,它们往往通过不断添加紧密耦合的关系来降低类的灵活性和模块性。这有点像在您的应用程序上浇注混凝土。它确实有效,但随着项目功能的变化,改变行为变得困难。

静态成员!=实例成员

非常清楚地注意,静态成员“属于”类本身,而不是该类的实例。静态成员无权访问实例成员。当您想要在逻辑中混合这些成员时,这会导致麻烦。你倾向于使一切都变得静止(所谓的“静态粘附”效应)。静态模式经常被认为是“反”的面向对象,正是出于这个原因。一旦在静态模式上构建结构,您往往会失去许多使OOD强大的原则。

在小的情况下,它们非常好

所有人都说 - TweenLite是一个非常合适的静态模式的一个很好的例子 - 它是一个实用程序包,逻辑不依赖于它。这也许应该是你如何利用静力学的。

为了减少对静态甚至全局变量的依赖,它通常意味着编写更多代码,但获得的应用程序结构的灵活性通常非常值得。 @Marty_Wallace有一个非常好的解决方案imo。

得墨忒耳和报童

最后,我将仅提及Law of Demeter或最少知识原则,以及相关的Paperboy and the Wallet示例,这在静态讨论中经常被指出:

  
      
  • 每个单位应该对其他单位的知识有限:仅   单位“密切”与当前有关   单元。
  •   
  • 每个单位只应与其朋友交谈;不要和陌生人说话。
  •   
  • 只与您的直接朋友交谈。
  •   

希望能够对一个相当复杂且不常见的明显问题有所了解。

答案 1 :(得分:1)

这是使用static命名空间完成的,但我不鼓励使用它。

package
{
    public class Main
    {
        public static function sayHell():void
        {
            trace("hello!");
        }
    }
}

您现在可以从应用程序的任何位置调用sayHello()(假设您已导入该类)。

Main.sayHello();

您可以做的另一件事(使整个类可以从应用程序中访问)是创建一个引用类本身的静态属性:

package
{
    public class Something
    {
        public static var instance:Something;

        public function Something()
        {
            instance = this;
        }

        public function someFunction():void
        {
            trace('hello!');
        }
    }
}

你现在可以这样使用:

Something.instance.someFunction();

此处唯一需要注意的是,您需要为此创建一个Something实例,以便调用构造函数并定义instance


我会做什么

  1. 为应用程序中的所有对象创建基类
  2. 创建一个负责这些对象的经理类
  3. 在基类中创建一个setter来定义管理器
  4. 以下是一个例子:

    <强>基

    package
    {
        public class Base extends Object
        {
            private var _manager:Manager;
    
            public function set manager(m:Manager):void
            {
                _manager = m;
                init();
            }
    
            protected function init():void
            {
                manager.someFunction();
            }
    
            public function get manager():Manager{ return _manager; }
        }
    }
    

    <强>管理器

    package
    {
        public class Manager extends Object
        {
            public function someFunction():void
            {
                trace('hello!');
            }
        }
    }
    

    现在任何扩展Base的内容都可以通过Manager getter属性访问manager中的任何内容。您需要做的就是确保定义manager,这可以从任何扩展Base的内容中轻松实现,如下所示:

    var something:SomeExtendingClass = new SomeExtendingClass();
    something.manager = manager;
    

答案 2 :(得分:0)

您提供的示例只是一个静态方法,但要回答有关类的全局实例的问题:

package myPackage
{
    public var globalVariable:MyClass = new MyClass();
}

您可以通过以下方式访问它:

import myPackage.globalVariable;
trace(globalVariable);

答案 3 :(得分:0)

我认为您必须重新考虑以哪种方式命名您的课程。

您可以在运行时实例化所需的任何类,但要按名称访问实例,您必须在结构中进行更改。例如,你在LoaderMax中提到的getContent()函数,它所做的就是在数组中搜索与名称匹配的给定加载器等等。您可以阅读 name 变量注释以获取描述。

  

用于标识加载程序实例的名称。此名称可以提供给getLoader()getContent()方法,也可以随时跟踪。每个加载器的名称应该是唯一的。如果您没有定义一个,将自动创建一个唯一的名称,如“loader21”。

因此,在此系统中,如果您希望能够搜索它们,则必须为每个成员(在本例中为加载器)命名。因为如果我打电话给getClassInstance("myinstance"),那么“myinstance”代表什么?我应该在哪里命名?

那就是说,如果你只想用DisplayObjects ,你可以使用getChildByName。但同样,您必须为每个DisplayObject命名(只需设置 name 变量)。

希望这有帮助。