C# MVC模式中应该怎样区分应用程序逻辑(Controller层)和业务逻辑(Model层)?

 更新时间:2020年6月25日 11:28  点击:2915

现在的大部分框架都是 MVC 模式,但 MVC 三个部分怎么配合,这里做了一点总结:

基本原则:业务逻辑代码应该写在 M 里面,而应用程序逻辑应该写在 C 里面。V 只是单纯的展示数据。

举个简单例子吧:用户往购物车添加一个商品

用户点击商品的“添加到购物车”按钮,引起一次请求。服务器开始处理该请求,过程:

1、检查当前用户是否有权限(比如是否已经登录、用户帐户状态、是否可以购物等)
2、检查要添加的商品ID是否有效、
3、检查要添加的商品库存是否足够
4、将商品加入购物车,并保存购物车状态
5、反馈信息

在上述流程中:

1: 是应用程序逻辑(一般由框架实现):因为和“添加商品到购物车”这个业务没有直接关系
2: 业务逻辑:不能购买不存在的商品,这是业务进行的基本条件
3: 业务逻辑:商品库存决定了是否可以购买此商品,这是业务进行的基本条件
4: 业务逻辑
5: 应用程序逻辑

用代码表示的,可能像下面这样:

复制代码 代码如下:

// Cart控制器
class Controller_Cart
{
    function actionAddGoods()
    {
        $goods_id = (int)$_GET['goods_id'];
        Cart::instance()->add($goods_id)->save();
       
        echo '添加成功';
    }
}


// Cart 模型
class Cart
{
    /**
     * 购物车中的所有项目
     */
    public $items = array();
  
    /**
     * 单子模式,返回购物车对象的唯一实例
     */
    static function instance()
    {
        ...
    }
  
    function add($goods_id, $quantity = 1)
    {
        $goods = Goods::find($goods_id)->get();
        // 检查 id 和库存数
        if ($goods->id && $quantity > $goods->remaining)
        {
            // 添加商品到购物车
            $this->items[] = array($goods, $quantity);
        }
        else
        {
            throw new CartExecption('无效的商品 ID');
        }
        return $this;
    }
}


这个代码不完整,但是演示了最重要的部分,就是应用程序逻辑和业务逻辑的分离。
如果这个流程走下去,用户要结算了,那么代码如下:
复制代码 代码如下:

class Controller_Cart
{
    function actionCheckOut()
    {
        Cart::instance()->checkout();
       
        echo '成功';
    }
}
class Cart
{
    function checkout()
    {
        // 开启一个数据库事务
        ....
       
        try
        {
            // 创建一个新的订单对象
            // $this->owner 是当前购物车的所有者(用户)
            $order = new Order($this->owner);
           
            // 将购物车中的所有商品添加到订单中
            foreach ($this->items as $item)
            {
                list($goods, $quantity) = $item;
                $order->add($goods, $quantity);
            }
            // 保存订单
            $order->save();
           
            // 清空购物车
            $this->items = array();
        }
        catch (Exception $ex)
        {
            // 出错了,回滚事务
            ....
              
            // 再重新抛出异常
            throw $ex;
        }
       
        // 返回新建的订单
        return $order;
    }
}


class Order extends Model
{
    public $items;
  
    function add($goods, $quantity)
    {
        $this->items[] = array($goods, $quantity);
        return $this;
    }
  
    function save()
    {
        foreach ($this->items as $item)
        {
            list($goods, $quantity) = $item;
            // 保存订单时,减少订单中每一个商品的库存数
            $goods->decrRemaining($quantity);
        }
       
        // 调用父类的保存
        parent::save();
       
        return $this;
    }
}


结算的代码很容易理解:
1、调用购物车的 checkout() 方法
2、开启数据库事务,这样当保存订单失败时(例如库存数不够)则回滚,确保数据库内容没有受影响
3、将购物车中的所有商品添加到订单
4、调用订单对象的 save() 方法
  4.1、遍历订单的所有项目,减少商品的库存(如果此时失败,商品的 decrRemaining() 方法会抛出异常)
  4.2、调用模型父类的 save() 方法
5、清空购物车,返回新建的订单对象

整个流程我们假定创建订单就等同于客户确认订单,此时减少库存。也有可能是后台确认订单配货后才减少库存,这和卖家的经营策略有关。

这两个例子里面,业务逻辑都在模型中实现,控制器(也就是封装应用程序逻辑的层)仅仅完成处理输入数据、调用业务方法、反馈结果等任务。

[!--infotagslink--]

相关文章

  • C#实现简单的登录界面

    我们在使用C#做项目的时候,基本上都需要制作登录界面,那么今天我们就来一步步看看,如果简单的实现登录界面呢,本文给出2个例子,由简入难,希望大家能够喜欢。...2020-06-25
  • 浅谈C# 字段和属性

    这篇文章主要介绍了C# 字段和属性的的相关资料,文中示例代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下...2020-11-03
  • C#中截取字符串的的基本方法详解

    这篇文章主要介绍了C#中截取字符串的的基本方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-03
  • C#实现简单的Http请求实例

    这篇文章主要介绍了C#实现简单的Http请求的方法,以实例形式较为详细的分析了C#实现Http请求的具体方法,需要的朋友可以参考下...2020-06-25
  • C#连接SQL数据库和查询数据功能的操作技巧

    本文给大家分享C#连接SQL数据库和查询数据功能的操作技巧,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友参考下吧...2021-05-17
  • C#中new的几种用法详解

    本文主要介绍了C#中new的几种用法,具有很好的参考价值,下面跟着小编一起来看下吧...2020-06-25
  • 使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序)

    这篇文章主要介绍了使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • C#开发Windows窗体应用程序的简单操作步骤

    这篇文章主要介绍了C#开发Windows窗体应用程序的简单操作步骤,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-12
  • C#从数据库读取图片并保存的两种方法

    这篇文章主要介绍了C#从数据库读取图片并保存的方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2021-01-16
  • C#和JavaScript实现交互的方法

    最近做一个小项目不可避免的需要前端脚本与后台进行交互。由于是在asp.net中实现,故问题演化成asp.net中jiavascript与后台c#如何进行交互。...2020-06-25
  • C++调用C#的DLL程序实现方法

    本文通过例子,讲述了C++调用C#的DLL程序的方法,作出了以下总结,下面就让我们一起来学习吧。...2020-06-25
  • 轻松学习C#的基础入门

    轻松学习C#的基础入门,了解C#最基本的知识点,C#是一种简洁的,类型安全的一种完全面向对象的开发语言,是Microsoft专门基于.NET Framework平台开发的而量身定做的高级程序设计语言,需要的朋友可以参考下...2020-06-25
  • C#变量命名规则小结

    本文主要介绍了C#变量命名规则小结,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-09
  • C#绘制曲线图的方法

    这篇文章主要介绍了C#绘制曲线图的方法,以完整实例形式较为详细的分析了C#进行曲线绘制的具体步骤与相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • C# 中如何取绝对值函数

    本文主要介绍了C# 中取绝对值的函数。具有很好的参考价值。下面跟着小编一起来看下吧...2020-06-25
  • c#自带缓存使用方法 c#移除清理缓存

    这篇文章主要介绍了c#自带缓存使用方法,包括获取数据缓存、设置数据缓存、移除指定数据缓存等方法,需要的朋友可以参考下...2020-06-25
  • c#中(&&,||)与(&,|)的区别详解

    这篇文章主要介绍了c#中(&&,||)与(&,|)的区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
  • 经典实例讲解C#递归算法

    这篇文章主要用实例讲解C#递归算法的概念以及用法,文中代码非常详细,帮助大家更好的参考和学习,感兴趣的朋友可以了解下...2020-06-25
  • C#学习笔记- 随机函数Random()的用法详解

    下面小编就为大家带来一篇C#学习笔记- 随机函数Random()的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • C#中list用法实例

    这篇文章主要介绍了C#中list用法,结合实例形式分析了C#中list排序、运算、转换等常见操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25