做的很好的淘宝客网站,注册网站的费用,wordpress 文章分页代码,网站创建过程简介 MVC设计模式是在20世纪80年代发明的一种软件设计模式#xff0c;至今已被广泛使用#xff0c;后来被推荐为 Sun 公司 J2EE 平台的设计模式。 随着Web应用的商业逻辑包含逐渐复杂的公式分析计算、决策支持等#xff0c;使客户机越 来越不堪重负#xff0c;因此将系…
简介 MVC设计模式是在20世纪80年代发明的一种软件设计模式至今已被广泛使用后来被推荐为 Sun 公司 J2EE 平台的设计模式。 随着Web应用的商业逻辑包含逐渐复杂的公式分析计算、决策支持等使客户机越 来越不堪重负因此将系统的商业分离出来。单独形成一部分这样三层结构产生了。 其中‘层’是逻辑上的划分。[1-3] 体系结构 表现层Presentation layer包含表示 mvc模式的体系结构 [5] 代码、用户交互GUI、数据验证。 该层用于向客户端用户提供GUI交互它允许用户在显示系统中输入和编辑数据同时 系统提供数据验证功能。 业务逻辑层Business layer包含业务规则处理代码即程序中与业务 相关专业算法、业务政策等等。该层用于执行业务流程和制订数据的业务规则。业务逻 辑层主要面向业务应用为表示层提供业务服务。 数据持久层Persistence layer包含数据处理代码和数据存储代码。数据持久层主要包括数据存取服务负责与数据库管理系统如数据库之间的通信。 三个层次的每一层在处理程序上有各自明确的任务在功能实现上有清晰的区分 各层与其余层分离但各层之间存有通信接口。 [3] 编辑本段模式结构 视图数据的展现。 视图是用户看到并与之交互的界面。视图向用户 MVC设计模式中的三个模式结构 [6] 显示相关的数据并能接收用户的输入数据但是它并不进行任何实际的业务处理。视图可以向模型查询业务状态但不能改变模型。视图还能接受模型发出的数据更新事件从而对用户界面进行同步更新。 模型应用对象。 模型是应用程序的主体部分。 模型代表了业务数据和业务逻辑 当数据发生改变时它要负责通知视图部分一个模型能为多个视图提供数据。由于同一个模型可以被多个视图重用所以提高了应用的可重用性。 控制器逻辑处理、控制实体数据在视图上展示、调用模型处理业务请求。 当 Web 用户单击 Web 页面中的提交按钮来发送 HTML 表单时控制器接收请求并调用相应的模型组件去处理请求然后调用相应的视图来显示模型返回的数据。[2-3] 编辑本段优点 采用三层软件设计架构后软件系统在可扩展性和可复用性方面得到极大提高在资源分配策略设计合理运用的同时软件的性能指标得到提升系统的安全性也得到改善。 三层体系结构对Web应用的软件架构产生很大影响促进基于组件的设计思想 产生了许多开发Web层次框架的实现技术。较之两级结构来说三层结构修改和维护上 更加方便。目前开发B/S结构的Web应用系统广泛采用这种三层体系结构。 [3] 编辑本段运行机制 在 MVC 模式中Web 用户向服务器提交的所有请求都由控制器接管。接受到请求之后控制器负责决定应该调用哪个模型来进行处理然后模型根据用户请求进行相应的业务逻辑处理并返回数据最后控制器调用相应的视图来格式化模型返回的数据并通过视图呈现给用户。[3][7] 1.MVC模式概述 MVC 模式包括三个部分模型Model、视图VIEW和控制器CONTROLLER,分别对应于内部数据、数据表示、输入输出控制部分。模型
是软件独立于外部表现的内在抽象是包含了核心数据和逻辑功能计算的应用它独立于界面的表达。视图View是模型的外在表现。它从模型中获得
信息并在屏幕上加以显示。控制器Controller定义用户界面对用户输入的响应它的职责是对模型中任何变化的传播加以控制。确保用户界面和模型
之间的对应关系协调着模型和视图的工作。模型和视图的分离使得一个模型可以对应多个视图。模型、视图和控制器之间的关系如下图所示。用户输入表示
用户和用户界面之间的相互交互关系通过控制器把用户输入与用户界面连接起来。视图通过控制器来响应用户输入。视图和模型之间是相互协作的关系。
即一个是同得到用户的输入以此来改变模型状态。同时模型又将自己的改变状态通知给它的所有视图而视图在得知这些变化之后自己做相应
的改变将视图的改变及时展现给不同的用户。这样做的好处是将用户输入、用户界面的显示和模型分离开来减小了他们之间的耦合度。MVC将模型
与视图的分离不仅提高了系统的灵活性和复用性而且为用户软件界面的提议接哦故的研究奠定了基础。 MVCmodel-view-control这是一个架构模式也是一种开发模式。不论设计模式还是架构模式MVC都是最经典的模式。Symbian OS作为最热的手机开发平台之一Symbian OS是一个微内核的系统它应用了大量的模式进行高度模块化设计便于根据需求的变更和新环境进行扩展和改善适应。MVC便是其中一个模式。回顾一下MVC的含义吧MVC设计模式它提供一种能够分别修改软件的不同模块的能力提高软件的健壮性和复用性。MVC模式能够帮助软件的设计者使用面向对象的设计原则比如开闭原则通过继承而不是修改存在的基类增加新的代码和类来扩展设计。
Model包含和操作程序中的数据它最重要的部分是应用程序的数据结构
View定义数据模型向用户显示的方式View传递接收到的命令和请求给controllerView是图形接口它从Model读并且获取需要显示的数据给用户
Controller定义用户接口对收到的命令和请求的处理操作Model中的数据并更新ViewMVC可以使得开发者根据面向对象编程的基本原则来设计他们的应用程序开发者在实现之前必须决定应用程序的那些部分是可以扩展的哪些是不行的。设计阶段之后代码的开发从一些基类开始可以通过增加新的特别的类来扩展。MVC和OCP是一致的。在Symbian S60中MVC的使用是基于Avkon的GUI框架框架提供基类实现ModelView和Controller。这些类可以被应用程序设计者扩展。
Avkon的基类
-CAknApplication应用程序的基类
-CAknDocumentModle的基类
-CAknAppUIController的基类
View的父类AVkon没有提供但是可以从CONE环境继承。
应用程序架构(Application Framework) 1、S60应用程序架构 S60平台在底层Uikon应用程序框架上添加了一个用户界面层(Avkon)。Avkon提供了一套特别为S60设计的UI组件和应用程序框架。 1.1、S60应用程序结构 1.1.1、模型(Model)—视图(View)—控制器(Controller)模式(MVC) MVC模式在S60 UI应用程序中是一个通用的设计模式。应用程序被分离成不同的逻辑部分它们包装了应用程序的不同方面。每个部分都用特殊的任务。MVC模式分离了应用程序设计使模型(Model)的代码得到重用。 模型(Model):封装了应用程序的状态和功能。通知视图(View)进行切换。响应来自视图(View)的状态查询。 视图(View):呈现模型(View)。接收来自模型(Model)的视图更新通知。将用户的输入发送给控制器(Controller)。 控制器(Controller)定义了应用程序的行为。将用户操作与模型(Model)更新相映射。响应视图(View)切换请求。1.1.2、S60应用程序结构和MVC S60应用程序通常分离成两大部分引擎(Engine)和UI。应用程序引擎也就是应用程序模型用来处理逻辑运算和数据结构表示。应用程序UI用来在屏幕上显示应用程序的数据和全部的行为。在基于S60应用程序框架下实现引擎和UI分离模式有三种方式:传统的Symbian OS应用程序构架、对话框构架、视图切换构架。不同的构架只反映UI的实现应用程序类(CAknApplication继承类)和文档类(CAknDocument)并没有区别。应用程序UI的组成: CAknApplication继承类: 应用程序框架的启动对象。 定义了应用程序的性质。 创建文档(CAknDocument)类。 CAknDocument继承类: 创建AppUi(Controller)。 提供了应用程序数据的持久化功能。 CAknAppUi或CAknViewAppUi继承类(Controller): 基类的选择依赖于应用程序架构。 处理应用程序事件。 控制应用程序模型(Model)。 负责切换视图(View)。 CCoeControl继承类(View): 显示模型(Model)状态。 接收用户输入。 向控制器通知相关事件。 根据模型(Model)变化更新显示。应用程序引擎(Engine): 封装了应用程序数据和状态。 封装了非UI依赖的功能能够在其他UI平台重用。 通常以类库的形式实现。 由AppUi直接操作。1.2、传统的Symbian OS 应用程序架构 1.3、对话框(Dialog)架构 1.4、视图切换架构 视图切换架构是一种机制它允许应用程序注册视图并且在任意时刻只有一个视图被激活。视图切换架构并没有规定视图的具体内容而是为视图在屏幕上显示提供了支持。 与传统的Symbian OS应用程序架构不同的是AppUi类(Controller)继承自CAknViewAppUi并且引入了一个新类CAknView作为AppUi(Controller)和容器(Control)之间的媒介。在视图切换架构中CAknView派生类称为Avkon视图(View),它拥有一个容器。AppUi创建每个Avkon视图并且在服务器端进行注册。切换视图时使用视图UID进行切换。 1.4.1、创建视图 CAknView派生类实例的创建通常在AppUi对象的ConstructL()方法中进行。该方法中将所有的视图进行注册并设置一个默认视图: void CMyViewArchAppUi::ConstructL() { BaseConstructL(); CMyViewArchAppView1* view1 new(ELeave) CMyViewArchAppView1; CleanupStack::PushL(view1); view1-ConstructL(); AddViewL(view1); // Transfer ownership to CAknAppUi. CleanupStack::Pop(); // pop view1. CMyViewArchAppView2* view2 new(ELeave) CMyViewArchAppView2; CleanupStack::PushL(view2); view2-ConstructL(); AddViewL(view2); // Transfer ownership to CAknAppUi. CleanupStack::Pop(); // pop view2. SetDefaultViewL(*view1); // More code } 另外视图本身并不具有绘制控件的能力所以每个视图需要包含派生自CCoeControl和MCoeControlObserver的控件容器: class CMyViewArchAppView1Container : public CCoeControl, MCoeControlObserver 1.4.2、Avkon视图类 每个Avkon视图类就像一个小型的AppUi。它必须提供一个Id()函数从而系统可以标识这个视图并且必须实现DoActivateL()和DoDeactivate()函数来完成视图激活和注销时的具体操作此外还应该实现HandleForegroundEventL()、HandleCommandL()和HandleStatusPaneSizeChange()函数用于处理各种事件。 DoActivateL() 当视图被激活时将调用该函数。该函数负责实例化并显示视图的控件。在视图被注销前可能多次调用该函数所以实现该函数必须考虑重复实例化控件。 DoDeactivate() 当视图被注销时将调用该函数负责销毁视图中的控件。只有当应用程序退出时或者激活同一个程序的另一个视图时激活的视图才被注销。该函数不能异常退出。 HandleForegroundEventL() 该函数只有当视图处于激活状态下才会被调用也就是在DoActivateL()调用之后和DoDeactivate()调用之前这段时间。当视图到达前台时视图将接收到HandleForegroundEventL(ETrue)。当视图从前台被移除时视图将接受到HandleForegroundEventL(EFalse)。只用视图在前台的状态实际改变时才会调用该函数。因为拥有视图的应用程序可能在前台和后台间来回切换多次所以该函数会被调用多次。函数的实现可能用来设置焦点或控制屏幕更新。 HandleCommandL() 当视图的菜单发出消息事件时时该函数将调用来处理菜单事件。 HandleStatusPaneSizeChange() 由于状态面板的改变导致客户区域大小的变化将调用该函数。 视图在活动期间接收事件的典型顺序: 1. DoActivateL()
2. HandleForegroundEventL(ETrue)
3. HandleForegroundEventL(EFalse)
4. DoDeactivate() 成对出现HandleForegroundEventL()可能在视图活动期间多次调用。DoActivateL()可能在DoDeactivate()调用之前多次调用。 1.4.3、视图资源(AVKON_VIEW) 典型情况下视图都需要拥有菜单项或CBA。通过将视图资源(AVKON_VIEW)的ID传递给视图的BaseConstructL()方法可以很容易为每个视图提供自己唯一的菜单项。 RESOURCE AVKON_VIEW {
hotkeys ;
menubar ;
cba ;
} 1.4.4、视图切换 本地视图切换 本地视图切换就是在同一应用程序内进行视图切换。切换时只需要指定需要切换视图的UID: ActivateLocalViewL( TUid::Uid(1) ); 外部视图切换 2、事件处理 2.1、命令(Commands)事件 命令事件是由Avkon框架产生用来响应用户选择菜单项和系统特殊事件。AppUi或Avkon视图将会通过HandleCommandL()方法处理命令事件。 2.1.1、AppUi对命令事件的处理 在传统的应用程序架构中AppUi的HandleCommandL()方法将处理命令事件。 void CContainerAppUi::HandleCommandL(TInt aCommand)
{
switch (aCommand)
{
case EEikCmdExit:
{
Exit();
break;
}
case ECmdXXX:
{
// implementation of cut operation
break;
}
...
default:
break;
}
} 用户自定义的命令ID(如ECmdXXX)在.hrh文件中定义Avkon系统命令ID(如EAknSoftKeyBack)定义在avkon.hrh中。EEikCmdExit是系统标准的应用程序退出命令ID。 2.1.2、Avkon视图对命令事件的处理 在视图切换应用程序架构中当前视图的HandleCommandL()方法将处理命令事件。 void CMyAppView1::HandleCommandL(TInt aCommand)
{
switch (aCommand)
{
case EMyAppCmdSwitchToView2: {
AppUi()-ActivateLocalViewL(KView2Id);
break; }
case ECmdXXX:
{
// Implement cut operation
break;
}
// ... Other view-specific command handling here
case EAknSoftkeyBack:
{
((MEikCommandObserver*)AppUi())-ProcessCommandL(EEikCmdExit);
break;
}
default: AppUi()-HandleCommandL(aCommand);
break;
}
} 2.2、按键事件与控件栈 按键事件是用户与应用程序交互时键盘所产生的事件。键被按下时被FEP转换成相应的键事件最终由应用程序框架传递给当前的应用程序。应用程序框架只将键事件传递给在控件栈中的对象。AppUi是缺省的键事件处理对象但是CCoeControl派生类的UI控件应该第一时间处理键事件。因此必须将控件放入控件栈中通常情况下由AppUi的AddToStackL()方法将控件放入控件栈中。 在传统和对话应用程序构架中在AppUi的构造阶段(Construction()方法)将控件放入控件栈控件将处于栈顶。当按键事件产生时应用程序框架首先要求处于栈顶的控件处理事件如果控件没有处理事件那么应用程序控件将要求栈中的第二个控件处理以此类推当栈中的所以控件都没有处理是将由AppUi的HandleKeyEventL()方法处理。 void CMyAppUi::ConstructL()
{
BaseConstructL();
iCurrentView CMyAppMainView::NewL(ClientRect());
AddToStackL(iCurrentView); // to enable key events
} 在视图切换应用程序架构中控件放入控件栈通常在视图对象的DoActivateL()中控件完成构造后进行。 void CMyView::DoActivateL(const TVwsViewId, TUid, const TDesC8)
{
if(!iUiControl) // iUiControl is CCoeControl-derived UI ctrl
{
iUiControl CMyUiControl::NewL(this, ClientRect());
AppUi()-AddToStackL(*this, iUiControl); // to ctrl stack.
}
} 当不希望该控件再接收按键事件时应该使用AppUi的RemoveFromStack()方法将控件移除控件栈。在视图切换应用程序机构中通常在视图对象的DoDeactivate()方法中实现从栈中移除控件。 void CMyView::DoDeactivate()
{
if(iUiControl)
{
AppUi()-RemoveFromStack(iUiControl); }
delete iUiControl;
iUiControl NULL;
} 在控件栈中的控件响应按键事件是通过调用他们的OfferKeyEventL()方法来实现的。调用的顺序是以控件在控件栈中的顺序进行最后放入的控件将先调用它的OfferKeyEventL()方法。OfferKeyEventL()方法必须重写因为它的默认实现不处理任何事件。当控件处理了事件就应返回EKeyWasConsumed因为如果返回EKeyWasNotConsumed应用程序框架将使控件栈中的下一个控件来处理。如果所以的控件都返回EKeyWasNotConsumed那么最后将在AppUi的HandleKeyEventL()方法中处理。 TKeyResponse CMyUiControl::OfferKeyEventL(const TKeyEvent aKeyEvent, TEventCode aType)
{
TKeyResponse response EKeyWasNotConsumed;
// pass key press events to the listbox. It will typically
// consume Up, Down, and Selection keys.
if (aType EEventKey iListBox)
{
response iListBox-OfferKeyEventL(aKeyEvent, aType);
}
return response;
}