Why there are no private constructors in AS3 version of Singleton?
Asked Answered
L

4

4

I am confused: In AS3, why do we keep the Singleton class constructor public and not private, like in Java? If we keep the constructor public, then we can directly access it from the outside!

Please check the MODEL part in this example.

Loupe answered 19/4, 2012 at 17:51 Comment(1)
Just FYI see: #138475. There is almost always a better way.Artificiality
Y
8

Actionscript 3 does not support private constructors.

In order to enforce the singleton pattern, many developers cause the constructor to raise an exception if there is already a singleton instance created. This will cause a runtime error, instead of a compile time error, but it does prevent the singleton's inappropriate use.


Example:

public static var instance:MySingleton;

public MySingleton(){
    if (instance != null) {
        throw new Error("MySingleton is a singleton. Use MySingleton.instance");
    }else {
        instance = this;
    }
}
Yours answered 19/4, 2012 at 17:55 Comment(1)
+1 for the correct info about constructors. Additionally, if you're using MVC anyway, consider RobotLegs (robotlegs.org) - it comes with integrated dependency injection (swiftsuspenders.org), which will make handling singletons and the MVC a lot easier.Impair
C
5

This blog post, in which Sho Kuwamoto (formerly of Macromedia / Adobe and heavily involved in the development of the Flex platform and tooling) explains the decision to omit private and protected constructors from ActionScript 3.0, may be of tangential interest.

Macromedia / Adobe's involvement in the developing ECMAScript 4 standard, and the decision to make ActionScript 3.0 adhere as closely to the specification as possible, meant that they were faced with the choice of either bodging these features, omitting them from the language completely, or waiting until they were standardised (and delaying the release of the language as a result).

Interesting, I think, because it shines a light on some of the key issues in the open versus proprietary standards debate.

Carolacarolan answered 20/4, 2012 at 0:7 Comment(0)
F
4

With the flex framework comes a class "Singleton" that allows you to
register a class to an interface.
With this method you can hide any functions you want just by not including it in the interface

// 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;
    }
}
Fundy answered 19/4, 2012 at 18:28 Comment(2)
It's also good to note that Flex managers (like PopupManager) are implemented this way. Hence, if you want to change a manager's behavior, you have to create your implementation class and register that class with the manager manually.Preform
@Preform Although out of scope of the question but good info regardless. I just want to add. Like all native flex singletons like the PopUpManager to implement your own version PopUpManagerImpl you have to do it in the Application preload event. It seems that all native Singletons are registered right after that event. And as you know being a Singleton once it is set you can't change it.Fundy
A
4

Here is an implementation of a singleton in AS with internal class usage:

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
}

See details here: http://www.swinburne.edu.au/design/tutorials/P-flash/T-How-to-build-a-Singleton-in-Actionscript-3/ID-143/

Amendatory answered 4/7, 2013 at 7:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.