关于MVC

 
关于MVC
 
sun的精辟解释(我以为问题阐述最好的)
Java BluePrints
Model-View-Controller
Context
Application presents content to users in numerous pages containing various data. Also, the engineering team responsible for designing, implementing, and maintaining the application is composed of individuals with different skill sets.
Problem
Now, more than ever, enterprise applications need to support multiple types of users with multiple types of interfaces. For example, an online store may require an HTML front for Web customers, a WML front for wireless customers, a Java TM (JFC) / Swing interface for administrators, and an XML-based Web service for suppliers
When developing an application to support a single type of client, it is sometimes beneficial to interweave data access and business rules logic with interface-specific logic for presentation and control. Such an approach, however, is inadequate when applied to enterprise systems that need to support multiple types of clients. Different applications need to be developed, one to support each type of client interface. Non-interface-specific code is duplicated in each application, resulting in duplicate efforts in implementation (often of the copy-and-paste variety), as well as testing and maintenance. The task of determining what to duplicate is expensive in itself, since interface-specific and non-interface-specific code are intertwined. The duplication efforts are inevitably imperfect. Slowly, but surely, applications that are supposed to provide the same core functionality evolve into different systems.
Forces
  • The same enterprise data needs to be accessed when presented in different views: e.g. HTML, WML, JFC/Swing, XML
  • The same enterprise data needs to be updated through different interactions: e.g. link selections on an HTML page or WML card, button clicks on a JFC/Swing GUI, SOAP messages written in XML
  • Supporting multiple types of views and interactions should not impact the components that provide the core functionality of the enterprise application
Solution
By applying the Model-View-Controller (MVC) architecture to a Java TM 2 Platform, Enterprise Edition (J2EE TM) application, you separate core business model functionality from the presentation and control logic that uses this functionality. Such separation allows multiple views to share the same enterprise data model, which makes supporting multiple clients easier to implement, test, and maintain.
Structure
The following diagram represents the Model-View-Controller pattern:
Participants & Responsibilities
The MVC architecture has its roots in Smalltalk, where it was originally applied to map the traditional input, processing, and output tasks to the graphical user interaction model. However, it is straightforward to map these concepts into the domain of multi-tier enterprise applications.
  • Model - The model represents enterprise data and the business rules that govern access to and updates of this data. Often the model serves as a software approximation to a real-world process, so simple real-world modeling techniques apply when defining the model.
  • View -The view renders the contents of a model. It accesses enterprise data through the model and specifies how that data should be presented. It is the view's responsibility to maintain consistency in its presentation when the model changes. This can be achieved by using a push model, where the view registers itself with the model for change notifications, or a pull model, where the view is responsible for calling the model when it needs to retrieve the most current data.
  • Controller - The controller translates interactions with the view into actions to be performed by the model. In a stand-alone GUI client, user interactions could be button clicks or menu selections, whereas in a Web application, they appear as GET and POST HTTP requests. The actions performed by the model include activating business processes or changing the state of the model. Based on the user interactions and the outcome of the model actions, the controller responds by selecting an appropriate view.
Strategies
·         Web-based clients such as browsers. JavaServer Pages TM (JSP TM) pages to render the view, Servlet as the controller, and Enterprise JavaBeans TM (EJB TM) components as the model. The Java Pet Store sample application illustrates this strategy.
·         Centralized controller. Instead of having multiple servlets as controllers, a main Servlet is used to make control more manageable. The Front Controller pattern describes this strategy in more detail.
·         Wireless clients such as cell phones. The Smart Ticket sample application illustrates this strategy.
Consequences
·         Re-use of Model components. The separation of model and view allows multiple views to use the same enterprise model. Consequently, an enterprise application's model components are easier to implement, test, and maintain, since all access to the model goes through these components.
·         Easier support for new types of clients. To support a new type of client, you simply write a view and some controller logic and wire them into the existing enterprise application.
·         Increased design complexity. This pattern introduces some extra classes due to the separation of model, view, and controller.
Related Patterns
[ BRMSS96]: Presentation-Abstraction-Control defines a structure with a hierarchy or cooperating agents, each with specific duties of the application functionality. It divides the functionality responsibilities into three components: presentation, abstraction, and control.
MVC meets Swing:Explore the underpinnings of the JFC's Swing components
以Button为例。
 
Swing中将mvc做了如下改变。
model
swing中的model基本有四类行为:
  • Query internal state
  • Manipulate internal state
  • Add and remove event listeners
  • Fire events
Button 中对应 ButtonModel
 
View和control
Button 中对应 ButtonUI 接口。
该接口负责按钮的可视化表示,以及处理输入。
 
Swing 中的 UI 有三类行为
  • Paint
  • Return geometric information
  • Handle AWT events
 
脚手架(scaffolding
程序员并不直接与上述三者打交道, java 通过 java.awt.Component 将三者隐藏起来。
或者说, Component 将三者组合在一起,是一个 wrapper
 
Swing 中的组件都是从 Component 继承来的。
java.lang.Object
 
 
java.awt.Component
      
 
java.awt.Container
          
 
javax.swing.JComponent
因此,与 AWT 组件一起使用时,基本没有问题。同时, swing 又模仿了 AWT 。即 AWT Button ,而 swing JButton
swing AWT 的继承者, AWT java 最初的 ui 解决方案)
 
 
举例:Button
 Button 做为按钮的 wrapper ,是 model view/control ui )的脚手架。
  这点正是如下体现的:
 
 public void setModel(ButtonModel buttonmodel)
   {
      if (this.buttonmodel != null)
      {
         this.buttonmodel.removeChangeListener(buttonchangelistener);
         this.buttonmodel.removeActionListener(buttonactionlistener);

         buttonchangelistener = null;
         buttonactionlistener = null;
      }

      this.buttonmodel = buttonmodel;

      if (this.buttonmodel != null)
      {
         buttonchangelistener = new ButtonChangeListener();
         buttonactionlistener = new ButtonActionListener();

         this.buttonmodel.addChangeListener(buttonchangelistener);
         this.buttonmodel.addActionListener(buttonactionlistener);
      }

      updateButton();
   }

   public void setUI(ButtonUI buttonui)
   {
      if (this.buttonui != null)
      {
         this.buttonui.uninstallUI(this);
      }

      this.buttonui = buttonui;

      if (this.buttonui != null)
      {
         this.buttonui.installUI(this);
      }

      updateButton();
   }

   public void updateButton()
   {
      invalidate();
   }
 
模型部分:
ButtonModel
管理三种状态: pressed armed selected
private boolean boolPressed = false;

   public boolean isPressed()
   {
      return boolPressed;
   }

   public void setPressed(boolean boolPressed)
   {
      this.boolPressed = boolPressed;

      fireChangeEvent(new ChangeEvent(button));
   }
管理事件:注册 add ,注销 remove ,激发 fire
private Vector vectorChangeListeners = new Vector();

   public void addChangeListener(ChangeListener changelistener)
   {
      vectorChangeListeners.addElement(changelistener);
   }

  public void removeChangeListener(ChangeListener changelistener)
   {
      vectorChangeListeners.removeElement(changelistener);
   }

   protected void fireChangeEvent(ChangeEvent changeevent)
   {
      Enumeration enumeration = vectorChangeListeners.elements();

      while (enumeration.hasMoreElements())
      {
         ChangeListener changelistener =
            (ChangeListener)enumeration.nextElement();

         changelistener.stateChanged(changeevent);
      }
   }
 
UI 部分:
ButtonUI
简单绘制
public void update(Button button, Graphics graphics)
   {
      ;
   }

   public void paint(Button button, Graphics graphics)
   {
      Dimension dimension = button.getSize();

      Color color = button.getBackground();

      graphics.setColor(color);

      graphics.fillRect(0,
                        0,
                        dimension.width,
                        dimension.height);
   }
 
处理 AWT 事件:
ButtonUI 不自己处理事件,而是通过一个事件监听器来完成处理工作。
view/controller相关类只是一组方法,不包括状态。所以,多个Button实例共用一个ButtonUI实例,通过不同的标识来区别。
private static ButtonUIListener buttonuilistener = null;

   public void installUI(Button button)
   {
      button.addMouseListener(buttonuilistener);
      button.addMouseMotionListener(buttonuilistener);
      button.addChangeListener(buttonuilistener);
   }

   public void uninstallUI(Button button)
   {
      button.removeMouseListener(buttonuilistener);
      button.removeMouseMotionListener(buttonuilistener);
      button.removeChangeListener(buttonuilistener);
   }
ButtonUIListener 帮助 Button ,将底层事件转换为符合 Button 模型处理要求,即 Button 模型能处理的语义事件,其实就是 Button 模型的三种状态。如下是如何从底层事件到语义事件。
   public void mouseDragged(MouseEvent mouseevent)
   {
      Button button = (Button)mouseevent.getSource();

      ButtonModel buttonmodel = button.getModel();

      if (buttonmodel.isPressed())
      {
         if (button.getUI().contains(button, mouseevent.getPoint()))
         {
            buttonmodel.setArmed(true);
         }
         else
         {
            buttonmodel.setArmed(false);
         }
      }
   }

   public void mousePressed(MouseEvent mouseevent)
   {
      Button button = (Button)mouseevent.getSource();

      ButtonModel buttonmodel = button.getModel();

      buttonmodel.setPressed(true);

      buttonmodel.setArmed(true);
   }

   public void mouseReleased(MouseEvent mouseevent)
   {
      Button button = (Button)mouseevent.getSource();

      ButtonModel buttonmodel = button.getModel();

      buttonmodel.setPressed(false);

      buttonmodel.setArmed(false);
   }

   public void stateChanged(ChangeEvent changeevent)
   {
      Button button = (Button)changeevent.getSource();

      button.repaint();
   }
 
 
 
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值