python: サンプルプログラムでMVCモデルの構成を掴む

プログラミング
スポンサーリンク




こんにちは、おみです。

最近仕事でGUIアプリケーションを作る機会がよくあります。

MVCモデルで、アプリケーションを開発していますが、ある程度理解できてきたので書き記そうと思います。

スポンサーリンク

MVCモデルとは…

GUIアプリケーションを開発するときのデザインパターンの一つ。

↓詳しい説明はこちら

Model View Controller - Wikipedia

要約すると…

Model … アプリケーションで扱うデータの管理や、処理の実行を行う。

View … アプリケーションの外見の定義を行う。

Controller … Model-View間でのデータの受け渡しを制御する。

デザインパターンを使用する利点

デザインパターンを利用する利点は何点かありますが、私は以下の2点が大きいと思います。

① スムーズにアプリケーション開発を行うことができる。

→ 同じデザインパターンで何回かアプリケーション開発を行うと、コーディングの流れを掴むことができ、スムーズに開発を行うことができます。

 

② 可読性の高いソースを記述できるようになる。

→コーディングの流れを掴むことができると、ただ処理を実装するのではなくどうしたら効率よく処理を行えるかまで考えれるようになり、その結果可読性の高いプログラムが作成できるようになります。また、デザインパターンが分かればある程度処理の流れを想像できるため、初めて見る人でも簡単にソースを読むことができます。

サンプルプログラムの説明

作成するプログラムは、挨拶を送信するプログラムです。

テキストボックスに相手の名前を入力し、[メッセージを送信ボタン]を投下すると

テキストボックスの下部に挨拶が表示されます。

ソースコード

↓ファイル構造はこんな感じです。

・Main.py

import tkinter as tk

from src.Model import Model
from src.View import View
from src.Controller import Controller


class Application(tk.Frame):
    def __init__(self, root):
        # スーパークラスのコンストラクタを呼び出し
        super().__init__(root)

        # モデルをインスタンス化
        self.model = Model(root)

        # ビューをインスタンス化
        self.view = View(root, self.model)

        # コントローラーをインスタンス化
        self.controller = Controller(root, self.model, self.view)

        # Viewにcommandを設定
        self.view.btn_submit["command"] = self.controller.btn_submit_clicked

        # 画面の設定
        root.geometry(str(self.model.width) + "x" + str(self.model.height))
        root.title(self.model.title)


# mainメソッド
def main():
    # 画面を生成
    root = tk.Tk()

    # 画面の設定を行う
    window = Application(root)

    # 画面を表示する
    window.mainloop()


if __name__ == "__main__":
    main()

・Model.py

import configparser as c
import tkinter as tk


class Model(object):
    def __init__(self, root):
        # ---------------------------------
        # 初期設定
        # ---------------------------------
        # configファイルを読み込み
        self.config = c.ConfigParser()
        self.config.read("config.ini")

        # 画面サイズを取得
        self.title = self.config["DISPLAY_INFO"]["title"]
        self.width = self.config["DISPLAY_INFO"]["width"]
        self.height = self.config["DISPLAY_INFO"]["height"]

        # 画面パーツに入力した値を格納する変数を宣言
        self.ent_choice_text = tk.StringVar()
        self.lbl_message_text = tk.StringVar()

    # ボタンクリック時起動メソッド
    def hello_execute(self):
        self.lbl_message_text.set("Hello {}!".format(self.ent_choice_text.get()))

・View

import tkinter as tk


class View(object):
    def __init__(self, root, model):
        self.root = root
        self.model = model

        # ---------------------------------
        # 画面の部品を生成
        # ---------------------------------
        # 入力欄ラベル
        self.lbl_choice = tk.Label(
            root,
            text="相手を入力"
        )

        # 入力欄
        self.ent_choice = tk.Entry(
            root,
            textvariable=model.ent_choice_text,
            width=30
        )

        # 送信ボタン
        self.btn_submit = tk.Button(
            root,
            text="メッセージを送信"
        )

        # 出力欄ラベル
        self.lbl_message = tk.Label(
            root,
            textvariable=model.lbl_message_text
        )

        # ---------------------------------
        # 画面の部品を配置
        # ---------------------------------
        self.lbl_choice.grid(row=0, column=0)
        self.ent_choice.grid(row=0, column=1)
        self.btn_submit.grid(row=0, column=2)

        self.lbl_message.grid(row=1, column=1)

・Controller

class Controller(object):
    def __init__(self, root, model, view):
        self.root = root
        self.model = model
        self.view = view

    # 挨拶ボタンクリック時の処理を定義
    def btn_submit_clicked(self):
        # モデルのメソッドを呼び出し
        self.model.hello_execute()

・config.ini

[DISPLAY_INFO]
title = "朝の挨拶送信"
width = 480
height = 50

MVCモデルの特徴

MVCモデルで特徴的な点は、Viewの入力情報をControllerがModelに受け渡し、Modelが実際にデータの処理を行う点です。

冒頭にも書きましたが、Controllerは処理の制御を行うクラスであり、実際の処理はModelで行います。

したがって、Viewから呼び出されるControllerのメソッドはViewで入力した値をModelに受け渡すための最低限の処理を記述し、受け取るModelのメソッドに実際の処理を記述します。

そうすることで画面と内部処理を明確に分割することができ、可読性が高いソースを書くことができます。

コメント

タイトルとURLをコピーしました