AS3 - 何时实施或扩展?

时间:2011-05-16 16:46:47

标签: actionscript-3 design-patterns

以多选问题游戏为例。

你有一个MathQuestion和WordQuestion类,如果它们实现了一个IQuestion接口,它定义了一个问题,答案和难度函数,或者更常见的是扩展一个问题基类,并覆盖这些函数?

哪种方法更正确?

2 个答案:

答案 0 :(得分:2)

这主要取决于你的课程的具体细节。如果类功能完全不同但共享功能/属性名称,则接口更合适。如果类共享很多常见的实现,那么子类更合适。

根据您的描述,这两个类似乎更适合具有不同实现的“相同功能/属性”类别,并且可能会更好地使用接口。

我通常使用接口过于强制执行一组类共享的常见行为,而在可以通过继承的函数/属性实现严格的代码重用的情况下,更适合使用子类。在一天结束时,它主要是一种设计选择。

答案 1 :(得分:2)

这是另一种思考问题的方式 - MathQuestion和WordQuestion之间是否有任何不同?对我而言,听起来它们都是问题对象,您可以通过composition来区分不同的类型。

您可以先定义一个Enum类,其中列出了测验中出现的不同类型的问题(严格来说,ActionScript 3没有正确的枚举,但我们仍然可以使用以下代码实现类型安全。 )

public class QuestionType {
    public static const MATH : QuestionType = new QuestionType("math");
    public static const WORLD : QuestionType = new QuestionType("world");

    private var _name : String;

    // Private constructor, do no instantiate new instances.
    public function QuestionType(name : String) {
        _name = name;
    }

    public function toString() : String {
        return _name;
    }
} 

然后,您可以在构造时将其中一个QuestionType常量传递给Question Class:

public class Question {
    private var _message : String /* Which country is Paris the capital of? */
    private var _answers : Vector.<Answer>; /* List of possible Answer objects */
    private var _correctAnswer : Answer; /* The expected Answer */
    private var _type : QuestionType; /* What type of question is this? */

    public function Question(message : String, 
                              answers : Vector.<Answer>, 
                              correctAnswer : Answer, 
                              type : QuestionType) {
        _message = message;
        _answers = answers.concat(); // defensive copy to avoid modification.
        _correctAnswer = correctAnswer;
        _type = type;
    }

    public function getType() : QuestionType {
        return _type;
    }
}

最后,客户端(使用Question对象的代码)可以轻松查询问题类型:

public class QuizView extends Sprite {
    public function displayQuestion(question : Question) : void {
        // Change the background to reflect the QuestionType.
        switch(question.type) {
            case QuestionType.WORLD:
                _backgroundClip.gotoAndStop("world_background");
                break;

            case QuestionType.MATH:
                _backgroundClip.gotoAndStop("math_background");
                break;
        }
    }
}