2011-11-10 12 views
6

Todo lo que hace el programa es hacer clic en un botón y le dice cuántas veces hizo clic en el botón en un campo de texto.¿Es esta una implementación correcta de MVC en Actionscript 3?

Clase de documento: este es el punto de entrada del código.

package { 
    import flash.display.MovieClip; 

    /** 
    * MVCTest.as 
    * @author rotaercz 
    */ 
    public class MVCTest extends MovieClip { 
     private var _model:Model; 
     private var _view:View; 
     private var _control:Control; 

     public function MVCTest() { 
      _model = new Model(); 
      _view = new View(this); 
      _control = new Control(_model, _view); 
     } 
    } 
} 

Clase de modelo: El código de modelo básico.

package { 

    /** 
    * Model.as 
    * @author rotaercz 
    */ 
    public class Model { 
     private var _totalClicks:int; 

     public function AddClick():void { 
      _totalClicks++; 
     } 

     public function get Clicks():int { 
      return _totalClicks; 
     } 

     public function Model() { 
      _totalClicks = 0; 
     } 
    } 
} 

Clase de control: controla tanto la entrada como la actualización del modelo y la vista aquí.

package { 
    import flash.events.MouseEvent; 

    /** 
    * Control.as 
    * @author rotaercz 
    */ 
    public class Control { 
     private var _model:Model; 
     private var _view:View; 

     public function Control(model:Model, view:View):void { 
      _model = model; 
      _view = view; 
      _view.addEventListener(MouseEvent.CLICK, OnClick); 
     } 

     private function OnClick(e:MouseEvent):void { 
      _model.AddClick(); 
      _view.Text = "clicked " + _model.Clicks; 
     } 
    } 
} 

Ver clase: La representación visual del programa.

package { 
    import flash.display.MovieClip; 
    import flash.events.EventDispatcher; 
    import flash.events.MouseEvent; 
    import flash.text.TextField; 

    /** 
    * View.as 
    * @author rotaercz 
    */ 
    public class View extends EventDispatcher { 
     private var _parent:MovieClip; 
     private var _button:MovieClip; 

     private var _dt:TextField; 

     public function set Text(s:String):void { 
      _dt.text = s; 
     } 

     public function View(parent:MovieClip) { 
      _parent = parent; 
      _dt = _parent.getChildByName("dt") as TextField; 
      _button = _parent.getChildByName("mcButton") as MovieClip; 
      _button.addEventListener(MouseEvent.CLICK, OnClick); 
     } 

     private function OnClick(e:MouseEvent):void { 
      dispatchEvent(e); 
     } 
    } 
} 
+0

si no planea usar métodos específicos en MovieClip (IE: 'gotoAndPlay()', etc.), debería usar Sprite en su lugar. Además, a diferencia de CPP, la convención para nombrar funciones de una clase (excepto para el constructor) comienza con minúsculas (IE: 'myFunction()' en vez de 'MyFunction()') – TheDarkIn1978

+0

, por supuesto, eso es simplemente una cuestión de estilo personal mientras se podría argumentar que esta convención es aún más confusa de tener solo el nombre del constructor comenzar con una letra mayúscula. – TheDarkIn1978

+2

, que de hecho es menos confuso, ES el constructor y, por lo tanto, refleja el nombre de clase. Tener miembros capitalizados es una gran IMO no-no, realmente no está claro si se está dirigiendo a un miembro de instancia miembro o miembro estático de una clase. – Creynders

Respuesta

3

En el modelo tradicional MVC la view tiene una dependencia directa del modelo tal como lo escribió www0z0k, pero yo también creo que no es una solución ideal.

La forma en que ha configurado su controlador, actúa como un mediador entre el modelo y la vista, y esa es ciertamente una solución muy válida.

Sin embargo, si desea una comunicación más directa del modelo para ver (le ahorrará algo de código) podría crear un eventdispatcher central, pasarlo a los modelos y dejarlos usar el evento central del evento para enviar sus eventos de actualización, luego también pase el evento central del evento a la vista y permita que la vista escuche los eventos enviados por los modelos directamente. De esta forma, la vista no tiene una dependencia directa de los modelos, pero aún puede escuchar los eventos que envían. En ese caso, el controlador solo traducirá los eventos de visualización a los modelos.

Diagrama: http://bit.ly/sTSDVT

El controlador actualiza el modelo directamente, pero también escucha al despachador de eventos central para actualizaciones desde el modelo (si es necesario) y los traduce a la vista. También escucha los eventos de vista

El modelo solo tiene una dependencia en el despachador de eventos y lo usa para despachar eventos de actualización.

La vista solo tiene una dependencia en el asignador de eventos y escucha la actualización de eventos del modelo. Distribuye sus propios eventos también. (Podría usar el despachador central de eventos para eso, pero no lo recomendaría)

0

controlador escucha para ver y actualizar el modelo, esta parte se ajusta a mi visión de MVC.
pero i había tratado de evitar la participación de controlador en modelo de unión a la vista:

_model = new Model(); 
    _view = new View(this, _model); 
    _control = new Control(_model, _view); 

en el modelo:

public class Model extends EventDispatcher{ 
    //............ 
    public function AddClick():void { 
     _totalClicks++; 
     dispatchEvent(new Event('one more click')); 
    } 

en vista:

private var _model:Model; 
    public function View(parent:MovieClip, model:Model) { 
     _parent = parent; 
     _model = model; 
     _model.addEventListener('one more click', update); 
     _dt = _parent.getChildByName("dt") as TextField; 
     _button = _parent.getChildByName("mcButton") as MovieClip; 
     _button.addEventListener(MouseEvent.CLICK, OnClick); 
    } 

    private function update(e:Event):void{ 
     _dt.text = _model.clicks; 
    } 
+0

Veo lo que hiciste allí. Entiendo que el Modelo ahora también está enviando eventos y la Vista está escuchando. Sin embargo, debe pasar la instancia _model al Constructor de Vista. La vista ahora requiere un _model para que funcione. ¿Por qué es esto mejor? Si hay varios Modelos que usan esta Vista, tendré que agregar detectores de eventos a Ver para cada uno de ellos. – rotaercz

+0

en tales casos, por lo general uso un despachador estático, por lo que para cada elemento ui agrego un oyente y cada cambio de valor de modelo causa un evento enviado por él, mientras que no necesito una referencia de modelo en mi vista – www0z0k

+0

Realmente no recomiendo utilizar un despachador estático, ya que vincula sus clases a una instancia específica. ¿Qué pasa si decides que quieres dos circuitos de despachadores de eventos en lugar de uno? Entonces estarás refaccionando todas tus clases. De hecho, las propiedades estáticas siempre se deben evitar, excepto en dos casos: constelaciones y propiedades que reflejan el estado de la clase (por ejemplo, un contador de instancias) – Creynders

0

Creo que mi Introduction to Flex Application’s Architecture - Redux le resultará de gran interés.

Para un enfoque más llamativo, puede consultar el FLit Framework. El MVCSprite es muy similar a su solución.

Jugando con tantos marcos a través de los años, llegué a creer que no es muy pragmático perseguir la implementación 'correcta' e 'ideal'. Los patrones de diseño no son formales: estas son solo ideas que siempre deben ajustarse de acuerdo con los atributos de calidad que está tratando de lograr. Tenga en cuenta que sería una ocasión muy rara para realmente clavar el enfoque en una sola iteración, a veces se necesitan muchos proyectos para completarse antes de encontrar una mejor manera, para obtener una visión más profunda.

+1

Introducción es un enlace roto, y los proyectos en Google Code se están cerrando. –

Cuestiones relacionadas