以OOP正确方式存储常用功能的位置

时间:2012-03-28 17:26:42

标签: actionscript-3 oop scope

我正在开展一个我想建立OO的项目。现在我带来了一个检查或值有效的函数。

private function valid(value:*, acceptedValues:Array):Boolean {
   for(var i:uint = 0; i < acceptedValues.length; i++) {
        if (value == acceptedValues[i]) {
            return true;
        }
    }
    return false;
}

如您所见,该功能非常通用,可以跨不同的类访问。 现在我的问题是;我在哪里以正确的方式存储它?

提前致谢!

5 个答案:

答案 0 :(得分:5)

我会在混乱中添加更多输入并说出来:

您不希望使用单一方法来验证您的值。今天,只传递一组有效值就足够了。但是明天,你会有类似电子邮件地址的东西来验证,然后你需要一个验证RegEx的方法。也许下个星期,您需要验证一组值,这些值来自取值的上下文,依此类推......

正如一条评论建议的那样,在这种情况下使用继承不是一个好主意 - 你会将你的验证与其余的代码紧密结合,迟早你会发现自己只在改变了很多东西一个简单的验证调用应该已经改变。同样适用于实用程序类:您会发现自己多次使用该类引用,如果您选择更改验证方法,则必须适应许多地方的大量更改。

所以,以优秀的OO方式,你最好使用一个接口,让我们称之为Validator并让你所有的验证类实现它:

public interface Validator {
    function validate ( value : * ) : Boolean;
} 

顺便说一下,这也是不使用静态类的最终原因:ActionScript中没有静态接口。

现在有些课程。让我们从您自己的验证方法开始,基于一系列值:

public class ArrayValidatorImpl implements Validator {
    private _validValues : Array;

    public function validate ( value : * ) : Boolean {
        return value in _validValues;
    } 

    public function ArrayValidatorImpl (validValues:Array ) {
        _validValues = validValues;
    }
}

...和电子邮件:

public class EmailValidatorImpl implements Validator {
    public function validate ( value : * ) : Boolean {
        var reg:RegExp = /(^[a-z0-9_\+-]+(\.[a-z0-9_\+-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*\.(ac|ad|ae|aero|af|ag|ai|al|am|an|ao|aq|ar|arpa|as|asia|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|biz|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cat|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|com|coop|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|edu|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gov|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|info|int|io|iq|ir|is|it|je|jm|jo|jobs|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mil|mk|ml|mm|mn|mo|mobi|mp|mq|mr|ms|mt|mu|museum|mv|mw|mx|my|mz|na|name|nc|ne|net|nf|ng|ni|nl|no|np|nr|nu|nz|om|org|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|pro|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tel|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|travel|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|xn|ye|yt|yu|za|zm|zw{2,4})$)/;
        return reg.exec( value.toString() );
    } 
}

现在您需要验证时,只需将接口实例传递给需要它的类,例如:

public class MyValidatingClass {
    private var _validator:Validator;

    public function myGreatMethod ( myValue : * ) : void {
        if( _validator.validate( myValue ) ) doStuffWith( myValue );
    }

    // ...

    public function MyValidatingClass( validator:Validator ) {
        _validator = validator;
    }
}  

如果您的要求发生变化,您可以简单地传递不同的实现,而无需再次触及MyValidatingClass的代码。干净,简单,松散耦合 - 随时可以在您编写的下一个程序中重复使用。然后是那个。等等...

答案 1 :(得分:4)

我会编写一个静态类(例如“Utility”),然后在其他类中调用该方法,如:

Utility.valid(...)

我认为,在AS3中你编写了一个静态方法,如:

public static function valid(...)

答案 2 :(得分:2)

虽然,这个Singleton对于这个问题是一个可以接受的答案我会认为这会有点过分杀人 但是,我将此作为对Amy Blankenship的回复 所以尽量不要投票。

// USAGE: is as simple as importing the class and then calling the method you want.
import com.utils.validate

// and then simple just doing
Validate.valid( someValue, someArray)

// Validate.as

package com.utils{
  import flash.utils.getDefinitionByName;
  import mx.core.Singleton;

  public class Validate{
    //private static var implClassDependency:ValidateImpl;
    private static var _impl:IValidate;

    // static methods will call this to return the one instance registered 
    private static function get impl():IValidate{
      if (!_impl)   {
        trace( 'registering Singleton Validate' )
        Singleton.registerClass("com.utils::IValidate",com.utils.ValidateImpl);
        _impl = IValidate( Singleton.getInstance("com.utils::IValidate"));
      }
      return _impl;
    }

    public static function valid(value:*, acceptedValues:Array):Boolean {
      return impl.valid( value, acceptedValues )
    }
  }
}

// IValidate.as

package com.utils{
  public interface IValidate {
    function valid(value:*, acceptedValues:Array):Boolean;
  }
}

// ValidateImpl.as

package com.utils{
  [ExcludeClass]
  // we can extends a class here if we need 
  public class ValidateImpl implements IValidate{
    // the docs say we need to include this but I donno about that
    // include "../core/Version.as";

    public function ValidateImpl (){
      // 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:IValidate;
    public static function getInstance():IValidate{
      if (!instance)
        instance = new ValidateImpl()
        return instance;
      }
    }

    private function valid(value:*, acceptedValues:Array):Boolean {
      for(var i:uint = 0; i < acceptedValues.length; i++) {
        if (value == acceptedValues[i]) {
          return true;
        }
      }
      return false;
    }
}

答案 3 :(得分:0)

创建一个帮助器类,然后可以提供给需要它的类。例如,Flex有一个名为Validator的专用类,以这种方式使用。您可以下载Flex SDK并查看Class以查看它是如何编写的。

用法如下:

protected var validator = new IsStringInArrayValidator();

//...

validator.validate(someString, someArray);

或者,您可以使用

valid = (someArray.indexOf(someString) > -1);

这可能不够复杂,无法担心封装它。

答案 4 :(得分:0)

包级别功能:

<强> validate.as

package utils 
{
    public function validate(array:Array, clazz:Class):Boolean
    {
        var flag:Boolean = true;

        for each(var obj:* in array)
        {
            if (!(obj is clazz))
            {
                flag = false;
                break;

            }// end if

        }// end for each

        return flag;

    }// end function

}// end package

Main.as(文档类)

package 
{
    import flash.display.Sprite;
    import flash.events.Event;
    import utils.validate;

    public class Main extends Sprite 
    {
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);

        }// end function

        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);

            var array1:Array = ["a", "b", "c"];
            var array2:Array = ["a", "b", 3];

            trace(validate(array1, String)); // output: true
            trace(validate(array2, String)); // output: false

        }// end function

    }// end class

}// end package