MVC
日本語 | 構造・画面・操作 |
英語 | Model-View-Controller |
ふりがな | えむぶいしー |
フリガナ | エムブイシー |
プログラムを「基本構造」「画面」「操作」の3つに分けること。
「Model-View-Controller」の略。
GUIプログラムを作る際に良く使用される、大まかに3つにプログラムを分ける方法のこと。
MVCでは、最も重要な処理の「モデル/model/基本構造」、ウィンドウやユーザーインターフェイスの「ビュー/view/画面」、そしてその2つを取り持つ「コントローラー/controller/操作」の3つにプログラムを分ける。
この分割を行わない場合、イベントハンドラの中に全処理を書き込んでしまったり、JSPに処理を記述したりということになる。
MVCを採用することで「プログラムの構造が明確になり可読性が高まる」「ビューとモデルの結合を疎にすることで、ビューやモデルの切り替えが簡単になる」「モデルにGUIのクラスが混ざらないためJUnitによる単体テストが行いやすい」等のメリットがある。
ただし「工数が増える」という単純な問題があり、古い体質のプロジェクトではあまり受け入れられていない。また「ビューはウィンドウでもブラウザでも良く種類を問わない」といった幻想による理想化され柔軟性に掛けたプログラムが作られたり、MVCそれぞれを別々のグループが作り最後の結合時にバグが大量発生したりと、完全に理解せずにプロジェクトに取り入れると最悪の結末を取りかねない。プロジェクトでMVCを採用する場合には、プロジェクト全体でのコンセンサスが不可欠である。
「Model-View-Controller」の略。
GUIプログラムを作る際に良く使用される、大まかに3つにプログラムを分ける方法のこと。
MVCでは、最も重要な処理の「モデル/model/基本構造」、ウィンドウやユーザーインターフェイスの「ビュー/view/画面」、そしてその2つを取り持つ「コントローラー/controller/操作」の3つにプログラムを分ける。
この分割を行わない場合、イベントハンドラの中に全処理を書き込んでしまったり、JSPに処理を記述したりということになる。
MVCを採用することで「プログラムの構造が明確になり可読性が高まる」「ビューとモデルの結合を疎にすることで、ビューやモデルの切り替えが簡単になる」「モデルにGUIのクラスが混ざらないためJUnitによる単体テストが行いやすい」等のメリットがある。
ただし「工数が増える」という単純な問題があり、古い体質のプロジェクトではあまり受け入れられていない。また「ビューはウィンドウでもブラウザでも良く種類を問わない」といった幻想による理想化され柔軟性に掛けたプログラムが作られたり、MVCそれぞれを別々のグループが作り最後の結合時にバグが大量発生したりと、完全に理解せずにプロジェクトに取り入れると最悪の結末を取りかねない。プロジェクトでMVCを採用する場合には、プロジェクト全体でのコンセンサスが不可欠である。
// Sample.java
import java.awt.Frame;
import java.awt.event.WindowListener;
import java.awt.event.WindowEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
public class Sample
{
public static void main( String[] args )
{
// ビューを作ります。
View view = new View( new Controller( new Model() ) );
}
}
/**
* ビュークラス。
*/
class View extends Frame implements WindowListener, MouseListener
{
/** コントローラークラスのインスタンス */
private Controller controller = null;
/**
* コンストラクタ。
*/
public View( Controller controller )
{
// ウィンドウを作ります。
super( "テストウィンドウ" );
// コントローラーのインスタンスをセットします。
this.controller = controller;
// ウィンドウイベントを受け取るイベントリスナーを追加します。
addWindowListener( this );
// マウスイベントを受け取るイベントリスナーを追加します。
addMouseListener( this );
// ウィンドウサイズをセットします。
setSize( 400 , 300 );
// ウィンドウを表示します。
setVisible( true );
}
/**
* ウィンドウが閉じようとするときに呼ばれるメソッド。
*/
public void windowClosing( WindowEvent windowEvent )
{
System.out.println( "View#windowClosing()" );
// ウィンドウの終了処理を行います。
dispose();
}
/**
* ウィンドウが閉じるときに呼ばれるメソッド。
*/
public void windowClosed( WindowEvent windowEvent )
{
System.out.println( "View#windowClosed()" );
System.exit( 0 );
}
/**
* 以下、その他イベントハンドラ。
* これらのメソッドはWindowListenerインターフェイスの
* メソッドなので、全てオーバーライドする必要があるためです。
*/
public void windowActivated( WindowEvent windowEvent )
{
System.out.println( "View#windowActivated()" );
}
public void windowDeactivated( WindowEvent windowEvent )
{
System.out.println( "View#windowDeactivated()" );
}
public void windowDeiconified( WindowEvent windowEvent )
{
System.out.println( "View#windowDeiconified()" );
}
public void windowIconified( WindowEvent windowEvent )
{
System.out.println( "View#windowIconified()" );
}
public void windowOpened( WindowEvent windowEvent )
{
System.out.println( "View#windowOpened()" );
}
/**
* クリックされました。
*/
public void mouseClicked( MouseEvent mouseEvent )
{
System.out.println( "View#mouseClicked()" );
}
/**
* 押されました。
*/
public void mousePressed( MouseEvent mouseEvent )
{
// 処理はControllerクラスで行います。
// そうすることで、Viewクラスに処理を詰め込まないようにします。
controller.mousePressed( mouseEvent );
// もちろん、プログラム的に、このメソッドの中に全処理を詰め込むという事もできます。
// ですが、そうなった場合に処理がこのメソッドに集中し、再利用性等が落ちます。
// また、マウスイベントのメソッドなのでJUnitの単体テストに使用しづらいという
// 問題点もあります。
}
/**
* 離されました。
*/
public void mouseReleased( MouseEvent mouseEvent )
{
// 処理はControllerクラスで行います。
// そうすることで、Viewクラスに処理を詰め込まないようにします。
controller.mouseReleased( mouseEvent );
}
/**
* マウスカーソルが入りました。
*/
public void mouseEntered( MouseEvent mouseEvent )
{
}
/**
* マウスカーソルが出ました。
*/
public void mouseExited( MouseEvent mouseEvent )
{
}
}
/**
* コントローラークラス。
*/
class Controller
{
/** モデルクラスのインスタンス */
private Model model = null;
/**
* コンストラクタ。
*/
public Controller( Model model )
{
this.model = model;
}
/**
* マウスボタンが押されました。
*/
public void mousePressed( MouseEvent mouseEvent )
{
// MouseEventクラスの情報をバラバラにして渡します。
// そうすることで、ModelクラスをViewクラスから独立させる
// ことができます。
model.printBegin( mouseEvent.getX(), mouseEvent.getY() );
}
/**
* 離されました。
*/
public void mouseReleased( MouseEvent mouseEvent )
{
// MouseEventクラスの情報をバラバラにして渡します。
model.printEnd( mouseEvent.getX(), mouseEvent.getY() );
}
}
/**
* モデルクラス。
*/
class Model
{
/**
* 押されました。
*/
public void printBegin( int x, int y )
{
// これが(一応)メインの処理。
System.out.println( "マウスのボタンが押されました[X:" + x + ",Y:" + y + "]" );
// このようにモデルに中心となる処理を記述することで、
// 「重要な箇所はここ」と切り分けられるため可読性やメンテナンス性が高まります。
// また、複数のビューがある場合にもこのクラスを使い回すことができます。
}
/**
* 離されました。
*/
public void printEnd( int x, int y )
{
System.out.println( "マウスのボタンが離されました[X:" + x + ",Y:" + y + "]" );
}
}
import java.awt.Frame;
import java.awt.event.WindowListener;
import java.awt.event.WindowEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
public class Sample
{
public static void main( String[] args )
{
// ビューを作ります。
View view = new View( new Controller( new Model() ) );
}
}
/**
* ビュークラス。
*/
class View extends Frame implements WindowListener, MouseListener
{
/** コントローラークラスのインスタンス */
private Controller controller = null;
/**
* コンストラクタ。
*/
public View( Controller controller )
{
// ウィンドウを作ります。
super( "テストウィンドウ" );
// コントローラーのインスタンスをセットします。
this.controller = controller;
// ウィンドウイベントを受け取るイベントリスナーを追加します。
addWindowListener( this );
// マウスイベントを受け取るイベントリスナーを追加します。
addMouseListener( this );
// ウィンドウサイズをセットします。
setSize( 400 , 300 );
// ウィンドウを表示します。
setVisible( true );
}
/**
* ウィンドウが閉じようとするときに呼ばれるメソッド。
*/
public void windowClosing( WindowEvent windowEvent )
{
System.out.println( "View#windowClosing()" );
// ウィンドウの終了処理を行います。
dispose();
}
/**
* ウィンドウが閉じるときに呼ばれるメソッド。
*/
public void windowClosed( WindowEvent windowEvent )
{
System.out.println( "View#windowClosed()" );
System.exit( 0 );
}
/**
* 以下、その他イベントハンドラ。
* これらのメソッドはWindowListenerインターフェイスの
* メソッドなので、全てオーバーライドする必要があるためです。
*/
public void windowActivated( WindowEvent windowEvent )
{
System.out.println( "View#windowActivated()" );
}
public void windowDeactivated( WindowEvent windowEvent )
{
System.out.println( "View#windowDeactivated()" );
}
public void windowDeiconified( WindowEvent windowEvent )
{
System.out.println( "View#windowDeiconified()" );
}
public void windowIconified( WindowEvent windowEvent )
{
System.out.println( "View#windowIconified()" );
}
public void windowOpened( WindowEvent windowEvent )
{
System.out.println( "View#windowOpened()" );
}
/**
* クリックされました。
*/
public void mouseClicked( MouseEvent mouseEvent )
{
System.out.println( "View#mouseClicked()" );
}
/**
* 押されました。
*/
public void mousePressed( MouseEvent mouseEvent )
{
// 処理はControllerクラスで行います。
// そうすることで、Viewクラスに処理を詰め込まないようにします。
controller.mousePressed( mouseEvent );
// もちろん、プログラム的に、このメソッドの中に全処理を詰め込むという事もできます。
// ですが、そうなった場合に処理がこのメソッドに集中し、再利用性等が落ちます。
// また、マウスイベントのメソッドなのでJUnitの単体テストに使用しづらいという
// 問題点もあります。
}
/**
* 離されました。
*/
public void mouseReleased( MouseEvent mouseEvent )
{
// 処理はControllerクラスで行います。
// そうすることで、Viewクラスに処理を詰め込まないようにします。
controller.mouseReleased( mouseEvent );
}
/**
* マウスカーソルが入りました。
*/
public void mouseEntered( MouseEvent mouseEvent )
{
}
/**
* マウスカーソルが出ました。
*/
public void mouseExited( MouseEvent mouseEvent )
{
}
}
/**
* コントローラークラス。
*/
class Controller
{
/** モデルクラスのインスタンス */
private Model model = null;
/**
* コンストラクタ。
*/
public Controller( Model model )
{
this.model = model;
}
/**
* マウスボタンが押されました。
*/
public void mousePressed( MouseEvent mouseEvent )
{
// MouseEventクラスの情報をバラバラにして渡します。
// そうすることで、ModelクラスをViewクラスから独立させる
// ことができます。
model.printBegin( mouseEvent.getX(), mouseEvent.getY() );
}
/**
* 離されました。
*/
public void mouseReleased( MouseEvent mouseEvent )
{
// MouseEventクラスの情報をバラバラにして渡します。
model.printEnd( mouseEvent.getX(), mouseEvent.getY() );
}
}
/**
* モデルクラス。
*/
class Model
{
/**
* 押されました。
*/
public void printBegin( int x, int y )
{
// これが(一応)メインの処理。
System.out.println( "マウスのボタンが押されました[X:" + x + ",Y:" + y + "]" );
// このようにモデルに中心となる処理を記述することで、
// 「重要な箇所はここ」と切り分けられるため可読性やメンテナンス性が高まります。
// また、複数のビューがある場合にもこのクラスを使い回すことができます。
}
/**
* 離されました。
*/
public void printEnd( int x, int y )
{
System.out.println( "マウスのボタンが離されました[X:" + x + ",Y:" + y + "]" );
}
}
// Sample.java import java.awt.Frame; import java.awt.event.WindowListener; import java.awt.event.WindowEvent; import java.awt.event.MouseListener; import java.awt.event.MouseEvent; public class Sample { public static void main( String[] args ) { // ビューを作ります。 View view = new View( new Controller( new Model() ) ); } } /** * ビュークラス。 */ class View extends Frame implements WindowListener, MouseListener { /** コントローラークラスのインスタンス */ private Controller controller = null; /** * コンストラクタ。 */ public View( Controller controller ) { // ウィンドウを作ります。 super( "テストウィンドウ" ); // コントローラーのインスタンスをセットします。 this.controller = controller; // ウィンドウイベントを受け取るイベントリスナーを追加します。 addWindowListener( this ); // マウスイベントを受け取るイベントリスナーを追加します。 addMouseListener( this ); // ウィンドウサイズをセットします。 setSize( 400 , 300 ); // ウィンドウを表示します。 setVisible( true ); } /** * ウィンドウが閉じようとするときに呼ばれるメソッド。 */ public void windowClosing( WindowEvent windowEvent ) { System.out.println( "View#windowClosing()" ); // ウィンドウの終了処理を行います。 dispose(); } /** * ウィンドウが閉じるときに呼ばれるメソッド。 */ public void windowClosed( WindowEvent windowEvent ) { System.out.println( "View#windowClosed()" ); System.exit( 0 ); } /** * 以下、その他イベントハンドラ。 * これらのメソッドはWindowListenerインターフェイスの * メソッドなので、全てオーバーライドする必要があるためです。 */ public void windowActivated( WindowEvent windowEvent ) { System.out.println( "View#windowActivated()" ); } public void windowDeactivated( WindowEvent windowEvent ) { System.out.println( "View#windowDeactivated()" ); } public void windowDeiconified( WindowEvent windowEvent ) { System.out.println( "View#windowDeiconified()" ); } public void windowIconified( WindowEvent windowEvent ) { System.out.println( "View#windowIconified()" ); } public void windowOpened( WindowEvent windowEvent ) { System.out.println( "View#windowOpened()" ); } /** * クリックされました。 */ public void mouseClicked( MouseEvent mouseEvent ) { System.out.println( "View#mouseClicked()" ); } /** * 押されました。 */ public void mousePressed( MouseEvent mouseEvent ) { // 処理はControllerクラスで行います。 // そうすることで、Viewクラスに処理を詰め込まないようにします。 controller.mousePressed( mouseEvent ); // もちろん、プログラム的に、このメソッドの中に全処理を詰め込むという事もできます。 // ですが、そうなった場合に処理がこのメソッドに集中し、再利用性等が落ちます。 // また、マウスイベントのメソッドなのでJUnitの単体テストに使用しづらいという // 問題点もあります。 } /** * 離されました。 */ public void mouseReleased( MouseEvent mouseEvent ) { // 処理はControllerクラスで行います。 // そうすることで、Viewクラスに処理を詰め込まないようにします。 controller.mouseReleased( mouseEvent ); } /** * マウスカーソルが入りました。 */ public void mouseEntered( MouseEvent mouseEvent ) { } /** * マウスカーソルが出ました。 */ public void mouseExited( MouseEvent mouseEvent ) { } } /** * コントローラークラス。 */ class Controller { /** モデルクラスのインスタンス */ private Model model = null; /** * コンストラクタ。 */ public Controller( Model model ) { this.model = model; } /** * マウスボタンが押されました。 */ public void mousePressed( MouseEvent mouseEvent ) { // MouseEventクラスの情報をバラバラにして渡します。 // そうすることで、ModelクラスをViewクラスから独立させる // ことができます。 model.printBegin( mouseEvent.getX(), mouseEvent.getY() ); } /** * 離されました。 */ public void mouseReleased( MouseEvent mouseEvent ) { // MouseEventクラスの情報をバラバラにして渡します。 model.printEnd( mouseEvent.getX(), mouseEvent.getY() ); } } /** * モデルクラス。 */ class Model { /** * 押されました。 */ public void printBegin( int x, int y ) { // これが(一応)メインの処理。 System.out.println( "マウスのボタンが押されました[X:" + x + ",Y:" + y + "]" ); // このようにモデルに中心となる処理を記述することで、 // 「重要な箇所はここ」と切り分けられるため可読性やメンテナンス性が高まります。 // また、複数のビューがある場合にもこのクラスを使い回すことができます。 } /** * 離されました。 */ public void printEnd( int x, int y ) { System.out.println( "マウスのボタンが離されました[X:" + x + ",Y:" + y + "]" ); } }
「みだし」に含まれているページ
「サンプルプログラムとか」に含まれているページ
- (参照している単語はありません)