2014/11/8 Developers.IO Meetup 10 
あなたのアプリ 
報・連・相できてますか? 
スマホアプリ開発あしたの為の環境と設計のアプローチ 
Copyright © Classmethod, Inc. 1 
横山U大
こんにちは 
横山U大(27) 
北海道釧路市出身 
Copyright © Classmethod, Inc. 2 
これまで 
• 建設業(設計・施工) 
• ミュージシャン気取り 
• 飲食業店長 
今のお仕事 
• Android エンジニア 
• デザイン 
• プロジェクトリーダー
今日のお話 
• MVPパターンについて 
• 実装例の解説 
• まとめ 
Copyright © Classmethod, Inc. 3
MVPパターンについて 
Copyright © Classmethod, Inc. 4
MVPパターンについて 
MVCって 
よく聞くよね 
もう少し柔軟に 
MVPパターン 
(Model – View – Presenter) 
Copyright © Classmethod, Inc. 5
MVPパターンについて 
Model 
View 
Presenter 
MVC のModel と同様にドメインロジックのみ 
を持つ。 
Model はView やPresenter に依存しない。 
画面の表示とユーザー入力の受付を担当する。 
ユーザー入力はPresenter に渡す。 
MVC のようなModel の監視は必須ではない。 
MVC のController とは違い、UI のビジネスロ 
ジックを含みインタフェースを通じてView を 
操作する。 
Copyright © Classmethod, Inc. 6
実装例の解説 
Copyright © Classmethod, Inc. 7
実装例の解説 
超 
ラッキー 
今日の運勢 
• 今日の運勢ボタンを押す 
• 今日の運勢を取得する 
• 今日の運勢を表示する 
楽勝だね 
Copyright © Classmethod, Inc. 8
MVPパターンを利用しない場合 
Copyright © Classmethod, Inc. 9
実装例の解説– MVPパターンを利用しない場合 
public class MainActivity extends Activity implements OnClickListener { 
private DivinationManager mDivinationManager; 
private Button mButton; 
private TextView mTextView; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.activity_main); 
mDivinationManager = new DivinationManager(); 
mTextView = (TextView)findViewById(R.id.textView); 
mButton = (Button)findViewById(R.id.button); 
mButton.setOnClickListener(this); 
} 
Copyright © Classmethod, Inc. 10
実装例の解説– MVPパターンを利用しない場合 
@Override 
public void onClick(View v) { 
showProgress(); 
mDivinationManager.get(new DivinationDelegate() { 
@Override 
public void completeDivination(String result) { 
mTextView.setText(result); 
dismissProgress(); 
} 
}); 
} 
private void showProgress() { ・・・} 
private void dismissProgress() { ・・・} 
} 
Copyright © Classmethod, Inc. 11
実装例の解説– MVPパターンを利用しない場合 
public class DivinationManager { 
public static interface DivinationDelegate { 
void completeDivination(String result); 
} 
public void get(DivinationDelegate delegate) { 
・・・ 
delegate.completeDivination("result"); 
} 
} 
Copyright © Classmethod, Inc. 12
実装例の解説– MVPパターンを利用しない場合 
機能が増えたらActivity が肥大化して 
いくよね 
UI ロジックのテストをするには 
Android 端末で実行する必要があるな 
Copyright © Classmethod, Inc. 13
MVPパターンを利用した場合 
Copyright © Classmethod, Inc. 14
実装例の解説 
ユーザーの入力を 
Presenter に渡す 
Copyright © Classmethod, Inc. 15 
Model に 
メッセージを送る 
Presenter に 
データを提供する 
Presenter が 
View を操作する
実装例の解説– MVPパターンを利用した場合 
public class MainActivity extends Activity implements IMainActivity, 
OnClickListener { 
private MainPresenter mMainPresenter; 
private Button mButton; 
private TextView mTextView; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.activity_main); 
mPresenter = new MainPresenter(); 
mPresenter.setView(this); 
mTextView = (TextView)findViewById(R.id.textView); 
mButton = (Button)findViewById(R.id.button); 
mButton.setOnClickListener(this); 
} 
Copyright © Classmethod, Inc. 16
実装例の解説– MVPパターンを利用した場合 
@Override 
public void onClick(View v) { 
mPresenter.startDivination(); 
} 
@Override 
public void showProgress() { ・・・} 
@Override 
public void dismissProgress() { ・・・} 
@Override 
public void setResultText(String result) { 
mTextView.setText(result); 
} 
} 
Copyright © Classmethod, Inc. 17
実装例の解説– MVPパターンを利用した場合 
public interface IMainActivity { 
void showProgress(); 
void dismissProgress(); 
void setResultText(String result); 
} 
Copyright © Classmethod, Inc. 18
実装例の解説– MVPパターンを利用した場合 
public class MainPresenter { 
private IMainActivity mView; 
private IDivinationManager mDivinationManager; 
public MainPresenter() { 
mDivinationManager = new DivinationManager(); 
} 
public void setView(IMainActivity view) { 
mView = view; 
} 
public void startDivination() { 
mView.showProgress(); 
mDivinationManager.get(new DivinationDelegate() { 
@Override 
public void completeDivination(String result) { 
mView.setResultText(result); 
mView.dismissProgress(); 
} 
}); 
} 
} 
Copyright © Classmethod, Inc. 19
実装例の解説– MVPパターンを利用した場合 
public interface IDivinationManager { 
void get(DivinationDelegate divinationDelegate); 
} 
public class DivinationManager implements IDivinationManager { 
public static interface DivinationDelegate { 
void completeDivination(String result); 
} 
@Override 
public void get(DivinationDelegate delegate) { 
・・・ 
delegate.completeDivination("result"); 
} 
} 
Copyright © Classmethod, Inc. 20
実装例の解説 
ユーザーの入力を 
Presenter に 
報告する 
Copyright © Classmethod, Inc. 21 
報告の内容を 
Model に 
連絡する 
自分では解決できないことを 
データ層に相談する
実装例の解説– MVPパターンを利用した場合 
Presenter はView の実装に依存しない 
から、UI ロジックのテストが容易にな 
るね! 
少し強引だけど、MVPパターンは 
報・連・相パターンだね!! 
Copyright © Classmethod, Inc. 22
まとめ 
Copyright © Classmethod, Inc. 23
MVPパターンを利用すると 
• UIロジックのテストが実行しやすくな 
る(Viewが差し替えできる) 
• コードが役割毎に分離されてActivity 
が肥大化しずらくなる 
• 実装にルールができるので、いちいち 
迷わなくなる 
• 実装の説明が上手になる 
Copyright © Classmethod, Inc. 24
変更に強い 
読みやすいテストしやすい 
アプリの報・連・相が有効 
Copyright © Classmethod, Inc. 25
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」

MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」

Editor's Notes

  • #6 MVCパターンについては一度は耳にしたことがあるのではないでしょうか? MVCパターンと一口に言っても、様々な派生パターンがあって人それぞれ認識が違ったりします。 アプリをMVCで作れ!といわれても、実際はまらないしパターンの規則をいたるところで破ってMVCといっている意味がなくなる
  • #22 ビューがモデルを監視するものを「監視コントローラ」、 ビューがモデルを監視しないものを「パッシブ・ビュー」と呼んで区別することもある。