Model,与数据库,框架和开发方式无关

来源:互联网 发布:用友软件erpu8 编辑:程序博客网 时间:2024/05/02 16:19

Model

与数据,框架和开方式无关

 

知识产权保护请从我做起,转载请注明出处。

http://blog.csdn.net/struts2

 

代码示例请参看:http://code.google.com/p/mdx-shopping

 

概述

Model就不得不提件开发领域著名的构架模式:MVC

 

MVC是一种件构架,在被认为件工程中使用的一种构架模式.这个模式将域逻辑(用户使用的应用程序逻辑)从用户界面(输入和表示)中分离出来,从而可以独立开发、测试和维护每一部分(关注分离)。

原文参看:

http://en.wikipedia.org/wiki/Model%E2%80%93View%E2%80%93Controller

 

MVC三个字母风别ModelViewController的首字母,一下这边文章主要探讨一下什么是Model,如何设计和实现Model

 

Model是什么

Model是什么:

要回答Model是什么,需要从理解Model的定义开始。

根据MVC的定义,Model是域逻辑,或者可以通俗地理解为用户需要使用的应用程序的逻辑,或者跟简单一些就是用户的需求。

 

用户需求通常包含两部分的内容,做什么操作和得到什么结果。

 

做什么操作就是需要帮助用户完成什么业务逻辑,毕竟软件的初衷就是帮助客户完成一些原本用户需要重复做的事情。

得到什么结果就是做完用户期望的操作之后,得到什么结果,或许这才是用户最期望的内容,通常情况下这些内容需要被保存下来。

 

概括起来说,Model就是用户操作和被操作的数据的结合体。

 

Mode不是什么:

(1)  Model是数据库吗?

简单地回答,不是。不过上面说过Model通常需要被存储起来,以供客户使用。而数据库又是最常见的数据存储的手段,所以可以这样说,Model的数据部分需通常存储在数据库中。

(2)  Model可以不包含用户逻辑吗?

通常情况下不可以。Model不进包含数据,也包含对这些数据的有意义的业务操作,只有数据结合了这些有意义的操作才真正成为了Model。没有业务逻辑的数据其实已经退化为了VO或者DTO

 

总结:

Model是业务逻辑和数据的结合体。业务逻辑体现了客户期望做什么,而数据体现了客户通过期望的操作想得到什么。

 

实例分析:

以下以用户管理为例,分析一下在这个CaseModel到底是什么。

 

通常的用户管理包含两个角色,第一是用户本身,第二是管理用户的管理员。

 

而需要做的操作可以按照角色的不同来分组:

l  对于用户本身来说,期望能够注册为系统的一个用户,希望能够使用注册用户登陆系统,同时希望能够定期修改密码。

l  对于管理员来说,希望能够了解总共有多少个用户,最好能够将用户分组管理,如果能够禁用默写用户就更好了。

 

在理解了这些需求的基础上,我们下面分析这个Case中的Mode

业务逻辑(或者可以说是操作)部分:

l  用户:注册,登陆,修改密码

l  管理员:查看所有用户,用户分组,启用和禁用用户。

数据部分:

根据常规的情况,至少需要用户登录名,密码和是否有效三个数据。

 

所以在用户管理的Case下,Model可以理解为:

现在可以点题了,Mode就是用户通常使用的操作和期望得到的结果,可以操作可以通过BS结构来完成,也可以通过CS结构来完成,可以存储在数据库中,也可以存储在文件系统中,可以使用Struts也可以不使用Struts而直接使用Servlet。可以给予J2EE当然也可以基于.NET平台。

 

Mode实现

尽管Model并不依赖于任何框架或者技术,但是为了讨论的方便,我们还是做了以下假定,在一下假定的范围内讨论Model的实现

l  使用Java语言

l  Model的数据部分保存在数据库中

l  使用MyBatis来简化数据保存的操作

 

Model实现的两种方式:

l  Manager(逻辑) + VO(数据):这种方式将数据与操作隔离,所有的操作都由Manager来完成,而VO通常承担了数据传输对象的作用,用来在前台ViewManager之间,以及Manager和数据库之间传递数据。本文中不详细讲解这种方式,这种方式较为普遍,请各位自行查阅。

l  Model(逻辑+数据):这种方式注重数据与操作的整合,一下主要探讨这种方式。

 

实例分析:

仍旧以用户管理为例逐步分析Model的实现。

第一步,数据部分首先应该添加在Model中,这部分内容比较简单,参看以下代码:

public class LoginInfoData extends ModelObject {

    private String username;

    private String password;

    private boolean isActive;

      

       // getter method and settermethod

}

第二部,将操作封装在Model中。但是在封装用户操作之前还有一个问题需要说明。用户操作分为两类,第一类,无中生有,第二类,有则改之。

 

无中生有最典型的操作是查看所有用户,而有则改之最典型的操作是修改密码。由于无中生有通常不是对某个单独的对象进行操作,所以通常设计为静态的类方法,而有则改之通常是对某一个具体实例的操作,所以通常设计为实例方法。参看以下代码:

public class LoginInfo extends LoginInfoData {

    /**

     * register user and connectrole of user to him.

     * @return true for success,false else

     */

    public boolean register() {

       //...

    }

   

    public staticList<LoginInfo> getAll() {

       //

    }

}

其他的通用方法:

对于单个对象的CRUD通常应该以一种共同的方式实现,或者使用代码自动生成。请注意上述代码的继承层次关系。

 

Mode使用:

用户登录

protected boolean checkUserLoginInfo() {

 

    LoginInfo info = newLoginInfo();

   info.setUsername(getModel().getUsername());

 

    if (info.load() &&

info.getPassword().equals(Digester.crypt(getModel().getPassword()))){

        // add role id and role

        this.loginInfo = info;

        return true;

    } else {

        return false;

    }

}

 

密码修改:

public String changePassword() {

    log.debug("entercustomer/changepwd action, model:" + model);

 

    // 1. check password andrepassword

 

    if (!model.getPassword().equals(model.getRePassword())){

        return INPUT;

    }

 

    // 2. check old password

    LoginInfo info = newLoginInfo();

   info.setUsername(getModel().getUsername());

 

    if (!info.load() ||!info.getPassword().equals(Digester.crypt(getModel().getPassword()))) {

        // old user not exist orold password not equals

        return INPUT;

    }

 

    // 3. generate new passwordhash

    String newpwd =Digester.crypt(model.getPassword());

    info.setPassword(newpwd);

 

    // 4. update login info

    info.update();

 

    log.debug("updatepassword successfully!");

    return SUCCESS;

}