【问题标题】:Why there are no private constructors in AS3 version of Singleton?为什么 AS3 版本的 Singleton 中没有私有构造函数?
【发布时间】:2012-05-01 07:25:35
【问题描述】:

我很困惑:在 AS3 中,为什么我们保留 Singleton 类构造函数 public 而不是 private,就像在 Java 中一样?如果我们保留构造函数public,那么我们可以直接从外部访问它!

请查看this example中的MODEL部分。

【问题讨论】:

标签: actionscript-3 apache-flex actionscript flex3


【解决方案1】:

Actionscript 3 不支持私有构造函数。

为了强制执行单例模式,如果已经创建了单例实例,许多开发人员会导致构造函数引发异常。这将导致运行时错误,而不是编译时错误,但它确实防止了单例的不当使用。


例子:

public static var instance:MySingleton;

public MySingleton(){
    if (instance != null) {
        throw new Error("MySingleton is a singleton. Use MySingleton.instance");
    }else {
        instance = this;
    }
}

【讨论】:

  • +1 获取有关构造函数的正确信息。此外,如果您仍然使用 MVC,请考虑 RobotLegs (robotlegs.org) - 它带有集成的依赖注入 (swiftsuspenders.org),这将使处理单例 MVC 变得更加容易。
【解决方案2】:

这是一个在 AS 中使用内部类的单例实现:

package{
    public class Singleton{
        private static var _instance:Singleton=null;
        public function Singleton(e:SingletonEnforcer){
            trace("new instance of singleton created");
        }
        public static function getInstance():Singleton{
            if(_instance==null){
                _instance=new Singleton(new SingletonEnforcer());
            }
            return _instance;
        }
    }
} 
//I’m outside the package so I can only be accessed internally
class SingletonEnforcer{
//nothing else required here
}

在此处查看详细信息:http://www.swinburne.edu.au/design/tutorials/P-flash/T-How-to-build-a-Singleton-in-Actionscript-3/ID-143/

【讨论】:

    【解决方案3】:

    这个blog post,其中 Sho Kuwamoto(前身为 Macromedia / Adob​​e,并积极参与 Flex 平台和工具的开发)解释了从 ActionScript 3.0 中省略私有和受保护构造函数的决定,这可能是无关紧要的。

    Macromedia / Adob​​e 参与了 ECMAScript 4 标准的开发,以及使 ActionScript 3.0 尽可能地遵循规范的决定,这意味着他们面临的选择是要么隐藏这些功能,要么完全从语言中省略它们,或者等到它们被标准化(并因此延迟语言的发布)。

    我认为这很有趣,因为它揭示了开放与专有标准辩论中的一些关键问题。

    【讨论】:

      【解决方案4】:

      Flex 框架附带了一个“Singleton”类,它允许您
      将类注册到接口。
      使用此方法,您可以隐藏您想要的任何功能,只需不在界面中包含它即可

      // USAGE: is as simple as importing the class and then calling the
      // method you want.
      import com.samples.Sample
      
      // and then simple just doing
      trace( Sample.someFunction( ) ) // will return true
      

      // Sample.as

      package com.samples{
        import flash.utils.getDefinitionByName;
        import mx.core.Singleton;
      
        public class Sample{
          //private static var implClassDependency:SampleImpl;
          private static var _impl:ISample;
      
          // static methods will call this to return the one instance registered 
          private static function get impl():ISample{
            if (!_impl)   {
              trace( 'registering Singleton Sample' )
              Singleton.registerClass("com.samples::ISample",com.samples.SampleImpl);
              _impl = ISample( Singleton.getInstance("com.samples::ISample"));
            }
            return _impl;
          }
      
          public static function someFunction( ):Boolean {
            return impl.someFunction(   )
          }
        }
      }
      

      // ISample.as

      package com.samples{
        public interface ISample {
          function someFunction( ):Boolean;
        }
      }
      

      // SampleImpl.as

      package com.samples{
      
        // ExcludeClass will hide functions from the IDE
        [ExcludeClass]
        // we can extends a class here if we need 
        public class SampleImpl implements ISample{
          // the docs say we need to include this but I donno about that
          // include "../core/Version.as";
      
          public function SampleImpl (){
            // call super if we are extending a class
            // super();
          }
      
          // instance will be called automatically because we are
          // registered as a singleton
          private static var instance:ISample;
          public static function getInstance():ISample{
            if (!instance)
              instance = new SampleImpl()
              return instance;
            }
          }
      
      
          // public functions where we do all our code
          public function someFunction( ):Boolean {
            return true;
          }
      }
      

      【讨论】:

      • 还需要注意的是,Flex 管理器(如 PopupManager)是以这种方式实现的。因此,如果你想改变管理器的行为,你必须创建你的实现类并手动向管理器注册该类。
      • @Exort 虽然超出了问题的范围,但无论如何都是很好的信息。我只想补充。像 PopUpManager 之类的所有本机 flex 单例一样,要实现您自己的版本 PopUpManagerImpl 您必须在 Application preload 事件中执行此操作。似乎所有本地单例都在该事件之后立即注册。正如您所知,一旦设置为 Singleton,您将无法更改它。
      猜你喜欢
      • 1970-01-01
      • 2019-10-16
      • 1970-01-01
      • 2013-06-24
      • 1970-01-01
      相关资源
      最近更新 更多