美文网首页
Python 设计模式——MVC模式

Python 设计模式——MVC模式

作者: rollingstarky | 来源:发表于2021-01-06 22:37 被阅读0次

    模型 - 视图 - 控制器模式

    MVC 不仅仅是一种实现用户界面的软件模式,同时也是一种易于修改和维护的架构。通常 MVC 模式将应用程序分为 3 个基本部分:模型(Model)、视图(View)和控制器(Controller)。这 3 个部分相互关联,有助于将信息的处理与信息的呈现分开。

    MVC 模式的工作机制为:模型提供数据和业务逻辑(如何存储和查询信息),视图负责数据的展示(如何呈现),而控制器则是两者之间的粘合剂,根据用户要求的呈现方式协调模型和视图。视图和控制器依赖于模型,但模型是可以独立工作的。

    UML
    • 模型:定义针对数据的所有操作(如创建、修改和删除等),并提供与数据使用有关的方法
    • 视图:提供相应的方法,帮助根据上下文和应用程序的需要构建 Web 或 GUI 界面
    • 控制器:从请求接收数据,并将其发送到系统的其他部分。需要提供用于路由请求的方法

    MVC 模式的主要意图:

    • 将数据和数据的展示隔离开
    • 使类的维护和实现更加简单
    • 灵活地改变数据的存储和显示方式,两者相互独立

    模型是应用程序的基石,提供客户端请求的数据,必须在多个操作中保持一致。
    视图用来将数据展示在接口上供用户查看。可以独立开发,但不应包含复杂的逻辑;需要足够灵活,适应多种平台;应避免与数据库直接交互。
    控制器应该作为模型和视图之间的粘合剂,要尽可能薄;不应该进行数据库调用或参与数据的展示。

    示例代码

    class Model:
        services = {
            'email': {'number': 1000, 'price': 2},
            'sms': {'number': 1000, 'price': 10},
            'voice': {'number': 1000, 'price': 15}
        }
    
    
    class View:
        def list_services(self, services):
            for svc in services:
                print(svc, ' ')
    
        def list_pricing(self, services):
            for svc in services:
                print("For", Model.services[svc]['number'],
                      svc, 'message you pay $',
                      Model.services[svc]['price'])
    
    
    class Controller:
        def __init__(self):
            self.model = Model()
            self.view = View()
    
        def get_services(self):
            services = self.model.services.keys()
            return (self.view.list_services(services))
    
        def get_pricing(self):
            services = self.model.services.keys()
            return (self.view.list_pricing(services))
    
    
    if __name__ == '__main__':
        controller = Controller()
        print("Services Provided:")
        controller.get_services()
        print("Pricing for Services:")
        controller.get_pricing()
    
    # => Services Provided:
    # => email
    # => sms
    # => voice
    # => Pricing for Services:
    # => For 1000 email message you pay $ 2
    # => For 1000 sms message you pay $ 10
    # => For 1000 voice message you pay $ 15
    

    现实世界中的 MVC 模式

    目录结构:

    mvc
    ├── server.py
    └── templates
        ├── base.html
        ├── index.html
        └── new.html
    

    server.py 源代码:

    import tornado
    import tornado.web
    import tornado.ioloop
    import tornado.httpserver
    import sqlite3
    
    def _execute(sql):
        db = sqlite3.connect('sqlite3.db')
        cursor = db.cursor()
        cursor.execute(sql)
        res = cursor.fetchall()
        db.commit()
        db.close()
        return res
    
    
    class IndexHandler(tornado.web.RequestHandler):
        def get(self):
            query = "select * from task;"
            todos = _execute(query)
            print(todos)
            self.render('index.html', todos=todos)
    
    
    class NewHandler(tornado.web.RequestHandler):
        def post(self):
            name = self.get_argument('name', None)
            query = "create table if not exists task (id INTEGER \
                PRIMARY KEY, name TEXT, status NUMERIC);"
            _execute(query)
            query = "insert into task (name, status) values ('%s', %d);" % (name, 1)
            _execute(query)
            self.redirect('/')
    
        def get(self):
            self.render('new.html')
    
    
    class UpdateHandler(tornado.web.RequestHandler):
        def get(self, id, status):
            query = "update task set status=%d where \
                id=%s;" % (int(status), id)
            _execute(query)
            print(query)
            self.redirect('/')
    
    
    class DeleteHandler(tornado.web.RequestHandler):
        def get(self, id):
            query = "delete from task where id=%s;" % id
            _execute(query)
            self.redirect('/')
    
    
    class RunApp(tornado.web.Application):
        def __init__(self):
            Handlers = [
                (r'/', IndexHandler),
                (r'/todo/new', NewHandler),
                (r'/todo/update/(\d+)/(\d+)', UpdateHandler),
                (r'/todo/delete/(\d+)', DeleteHandler),
            ]
            settings = dict(
                debug=True,
                template_path='templates',
                static_path='static',
            )
            tornado.web.Application.__init__(self, Handlers, **settings)
    
    
    if __name__ == '__main__':
        http_server = tornado.httpserver.HTTPServer(RunApp())
        http_server.listen(5000)
        tornado.ioloop.IOLoop.instance().start()
    

    templates/base.html 源代码:

    <!DOCTYPE>
    <html>
      <head>
        {% block header %}{% end%}
      </head>
      <body>
        {% block body %}{% end %}
      </body>
    </html>
    

    templates/index.html 源代码:

    {% extends 'base.html' %}
    <title>ToDo</title>
    {% block body %}
    <h3>Your Tasks</h3>
    <table border="1">
      <tr align="center">
        <td>Id</td>
        <td>Name</td>
        <td>Status</td>
        <td>Update</td>
        <td>Delete</td>
      </tr>
      {% for todo in todos %}
      <tr align="center">
        <td>{{ todo[0] }}</td>
        <td>{{ todo[1] }}</td>
        {% if todo[2] %}
        <td>Open</td>
        {% else %}
        <td>Closed</td>
        {% end %}
        {% if todo[2] %}
        <td><a href="/todo/update/{{todo[0]}}/0">Close Task</a></td>
        {% else %}
        <td><a href="/todo/update/{{todo[0]}}/1">Open Task</a></td>
        {% end %}
        <td><a href="/todo/delete/{{todo[0]}}">X</a></td>
      </tr>
      {% end %}
    </table>
    
    <div>
      <h3><a href="/todo/new">Add Task</a></h3>
    </div>
    {% end %}
    

    templates/new.html 源代码:

    {% extends 'base.html' %}
    <title>ToDo</title>
    {% block body %}
    <div>
      <h3>Add Task to your List</h3>
      <form action="/todo/new" method="post" id="new">
      <p><input type="text" name="name" placeholder="Enter task" />
        <input type="submit" class="submit" value="add" /></p>
      </form>
    </div>
    {% end %}
    

    运行 python server.py 命令,浏览 http://localhost:5000/ ,效果如下:

    tasks add task

    PS:需安装 tornado 模块(pip install tornado

    相关文章

      网友评论

          本文标题:Python 设计模式——MVC模式

          本文链接:https://www.haomeiwen.com/subject/tdxmnktx.html