Presentation is loading. Please wait.

Presentation is loading. Please wait.

GUIアーキテクチャ・パターンの基礎から MVVMパターンへ

Similar presentations


Presentation on theme: "GUIアーキテクチャ・パターンの基礎から MVVMパターンへ"— Presentation transcript:

1 GUIアーキテクチャ・パターンの基礎から MVVMパターンへ
2012/8/4 わんくま同盟 大阪勉強会 #50 尾上雅則

2 本セッションの目的と動機付け 1.Introduction

3 Introduction - 目的 本セッションの目的は、 MVC/MVP/MVVMなどのいわゆるMVC系 GUIアーキテクチャ・パターン をMVVMパターンを通して適切に理解・学習・適用するための考え方を学ぶ事です。 MVVMパターンは XAML系プラットフォーム(WPF/SL/WP7/Metro) から生まれたMVC系パターンです。

4 Introduction -よくある説明 よくあるMVVMの図ですが これは何のために必要なんでしょう?
→ 保守性や変更容易性や開発生産性を確保するため → こんな事は全ての開発関連話題で当り前の事 問題は何を持ってそのメリットを確保するか

5 Introduction -よくある説明 Viewは表示で、Modelはドメインあるいはビジネスロジックとデータ、ViewModelはその橋渡し・・・? ドメインって? クラサバだとビジネスロジックはクライアントにないよ? Modelに書くべきことは結局どこからどこまで? Modelが曖昧だと当然橋渡しのViewModelもわからない

6 Introduction -よくある説明 納得したような気にはなりますが、 結局何も説明できていないんです
何をもって保守性や変更容易性や開発生産性を確保するか 説明できていない。 ViewModelは橋渡しって3つの責務が繋がってたら真ん中が橋渡しなのは当たり前でしょ?MVCもMVPもMVVMも全部一緒になる。 納得したような気にはなりますが、 結局何も説明できていないんです

7 Introduction –自己紹介+ 尾上 雅則 (おのうえ まさのり) 昭和58年生 フリーランス C#/MVVM
WindowsForms/ASPNET/XAML系全般など Blog – the sea of fertility – Twitter Facebook – MVVMer Microsot MVP for Visual C#(2012/7~) 日本でMVVMが流行り始めた2年前、その頃はまだ誰もView/ViewModel/Modelの各役割を説明できませんでした。説明は先ほど例示したそれのレベルでした

8 Introduction -方針 インターネット上にはMVC系パターンに関する知見があふれています。そのすべてが同じなわけではなく、さまざまな意見があります。 そういった状況でただ 「MVCでは○○は××する」 「MVVMでは△△は□□と解釈する」 などと言ってもそれを信じる根拠はありません。

9 Introduction -方針 本セッションでは私の2年間のうちのMVVMの概念に関わる認識をなぞり、MVVMパターンをまず導出していき、
導出の中で見出した目的・理由を武器に MVC系パターンの 本質はなんなのか どう理解するのか どう学習リソースを扱うのか どう適用していくのか について考えていきます。

10 Agenda Introduction GUIアプリケーションとPDS MVVMパターンとMVC系パターン MVC系パターンの学習方法
MVC系パターンの適用Tips まとめ

11 PresentationDomainSeparation
2.GUIアプリケーションとPDS

12 GUIアプリケーションとPDS Before PDS例
DomoSolution - BeforePDS コントロールの状態が制御判断に利用されている 責務分割されていない(この形のままじゃやりようが無い) 例えば色ではなく画像で表すことになったら変更範囲が大きい 責務分割されていないのでUIの変更から影響範囲が考察しにくい。 場合によってはイベントの処理順にビジネスフローが依存しかねない

13 GUIアプリケーションとPDS After PDS例
DomoSolution - AfterPDS コントロールの状態に依存しない状態制御手段を持った。 コードがBeforePDSより長い YourCondition.cs BeforePDSと比べてUIの変更にはるかに強い コードの見通しも良い イベントの処理順にビジネスフローが影響されたりすることもない。 しかしこの程度の規模では冗長さが目立つばかり Form1.cs

14 GUIアプリケーションとPDS PresentationDomainSeparation
この考え方の事を PresentationDomainSeparation(PDS) と呼びます。 本来当たり前のOOPです。関心事の分離です。 相互依存は望ましくないのでObserverパターンで!

15 GUIアプリケーションとPDS PresentationDomainSeparation
Martin Fowler (和訳) プレゼンテーションとドメインの分離 Martin Fowler‘s Bliki in Japan

16 GUIアプリケーションとPDS PresentationDomainSeparation
(引用):プレゼンテーションとドメインの分離 “最も有用な設計原則に、 プログラムのプレゼンテーション層(ユーザーインターフェイス)とその他の機能をうまく分ける、というのがあります。”

17 GUIアプリケーションとPDS PresentationDomainSeparation
分離することによる理解のしやすさ テストしにくいUIを分離してテスト容易部分を増やす 複数のプレゼンテーションで共有できるドメインができる プレゼン部分はそのプラットフォームの知識が本来別に必要である プレゼンプラットフォームの仕様・変更にドメインが引きずられない

18 GUIアプリケーションとPDS PresentationDomainSeparation
メリットは多く、OOPにおいてはそもそも至極真当な話です。 PDSしなかった事により発生するデメリットは、一般的なOOPがきちんとできなかった際のデメリットと同様です。規模の大きさに特に比例して影響範囲などの把握が難しくなります。 ただ全ユースケースでの処理の概要が一人でも一望できるほど規模が小さいプログラムでは冗長さが目立つかもしれません。

19 XAMLの事情とMVVM. そして他のMVCパターンへ 3.MVVMパターンとMVC系パターン

20 3.MVVMパターンとMVC系パターン Agenda
XAMLプラットフォームの特徴 XAMLでのPDS - MVVMパターン おまけ)ASP.NET MVCとMVC まとめ

21 3.MVVMパターンとMVC系パターン XAMLプラットフォームの特徴

22 MVVMパターンとMVC系パターン XAMLの特徴- ControlTemplate
外見の変化はカスタムコントロールを作る動機ではなくなった。 <TreeView> <ListBox> 画像貼りミス じゃないですよ!

23 MVVMパターンとMVC系パターン XAMLの特徴- CSSライクなレイアウトシステム
Windowサイズを広げてみる DomoSolution – BeforePDS/WPFLayout <WindowsForms> 残念。 <XAML> CSSと同じようなシステム

24 MVVMパターンとMVC系パターン XAMLの特徴 - VisualStateManager
コントロールに状態に応じた外観を定義する事が可能になった。(状態間にアニメーションの定義も可能/状態を追加する事も可能) 外観に関わるコードはこうやってほぼ全てXAMLに委譲できる。

25 MVVMパターンとMVC系パターン XAMLの特徴 – 双方向データバインド
WPF/Silverlightのデータバインディングは双方向のデータバインドに対応している

26 MVVMパターンとMVC系パターン XAMLの特徴 – DataTemplate
コレクションコントロール(ListBox/TreeView)などには最強の武器がある。

27 MVVMパターンとMVC系パターン XAMLの特徴 – コレクションコントロール
展開するまで 子のインスタンスが無い!

28 MVVMパターンとMVC系パターン XAMLの特徴 – コレクションコントロール
コレクションコントロールのはまり所 チェック状態をバインドで処理していないと・・・ DomoSolution - CollectionControl

29 MVVMパターンとMVC系パターン XAMLの特徴 – コレクションコントロール
コレクションコントロールのはまり所 WindowsPhoneではさらに状況は深刻 DomoSolution - PhoneListBox スクロール 関係ないところにチェックが!

30 MVVMパターンとMVC系パターン XAMLの特徴 – コレクションコントロール
画面のレンダリングに必要な動的に変化する情報を保持するバインドオブジェクトを設ける事で正常に動作する バインド!

31 MVVMパターンとMVC系パターン XAMLの特徴 – バインディングファースト
DataTemplateをC#/VBなどの汎用言語コードで構築しても全機能を使う事はできない。 コントロールの状態は信用しない。 コレクションコントロールの挙動などからも、メソッドどうこうより、バインドされたオブジェクトが正常にレンダリングされれば良いという哲学を感じる。 バインドするオブジェクトはコントロールの状態ストアとして機能する

32 MVVMパターンとMVC系パターン XAMLの特徴 – DSL

33 MVVMパターンとMVC系パターン XAMLの特徴 – DSL
バインディング・レンダリング機能を充実させるためにCLRプロパティとは別のプロパティシステムをも備える CSSライクなDSLをわざわざ介す事で、柔軟なレンダリング・レイアウトシステム、そして仮想化などを含むコントロールの自由な実装を手に入れた。

34 MVVMパターンとMVC系パターン XAMLの特徴 – まとめ
XAMLは外観の変化に非常に柔軟なDSL 外観の変化を動機としてC#/VBなどの汎用言語コードを書く事はほとんどない XAMLはバインディングファーストDSL メソッドやプロパティを直接触るのでは駄目で、バインディングじゃないとできない事があるくらい! バインドされたオブジェクトがコントロールの状態を決める PDSの説明で出てきた「プレゼンテーションプラットフォームの実装には汎用言語と異なった知識が必要」の典型例 WindowsFormsと比べると、XAML自体に対する知識がないと扱いにくい。WindowsFormsはC#に関する知識だけである程度できる。

35 3.MVVMパターンとMVC系パターン XAMLでのPDS - MVVMパターン

36 MVVMパターンとMVC系パターン XAMLでのPDS

37 MVVMパターンとMVC系パターン XAMLでのPDS
そしてXAMLにはXAML固有の都合でバインドするオブジェクトが必要となるので

38 MVVMパターンとMVC系パターン XAMLでのPDS

39 MVVMパターンとMVC系パターン XAMLでのPDS
View ViewModel Model この形の事をMVVMパターンと言います。 見ての通り全然特別なパターンではありません。

40 MVVMパターンとMVC系パターン XAMLでのPDS – MVVMパターン
View ViewModel Model

41 MVVMパターンとMVC系パターン XAMLでのPDS – MVVMパターン
Viewの都合で存在するViewModelを責務として分けている理由はなんでしょうか? Viewの都合であるものなのに、どうしてバインドするオブジェクトをViewのコードビハインドとかに書かないの?

42 MVVMパターンとMVC系パターン XAMLでのPDS – MVVMパターン
Viewの都合で存在するViewModelを責務として分けている理由はなんでしょうか? まず一つ目として使いまわしの視点があります。 ViewModelを書くのは手間です。使いまわせるところがあるなら使いまわしたいものです。 例えば詳細画面のViewModelを一覧画面でも使いたいなどがありませんか?

43 MVVMパターンとMVC系パターン XAMLでのPDS – MVVMパターン
Viewの都合で存在するViewModelを責務として分けている理由はなんでしょうか? また、Viewのクラスは基本的にDispatcherObjectと言って、単一のUIスレッド以外から触ると例外が出ます。 ViewModelの値はModelから更新されることがあるのに、これは現在ネットワークアクセスなどがすべて非同期を強要される方向に向かっている(すでにWPF以外すべての環境で強要されます)XAMLプラットフォームでは大きな問題です。 ViewModelをView内に記述するわけにはいかないのです。

44 MVVMパターンとMVC系パターン XAMLでのPDS – MVVMパターンまとめ
MVVMは「XAMLプラットフォームとPDS」という視点から当たり前に導き出されるものであり、それは特定の業務に向いているとか向いていないとかではありません。 MVVMは「XAMLプラットフォーム」で開発する以上考慮すべき考え方と言えます。

45 MVVMパターンとMVC系パターン XAMLでのPDS – MVVMパターンまとめ
MVVMパターンは、XAMLプラットフォームの力を存分に引き出して(それにはPDSが含まれる)設計を行うためのものです。

46 3.MVVMパターンとMVC系パターン おまけ)ASP.NET MVCとMVC

47 MVVMパターンとMVC系パターン おまけ)ASP.NET MVCとMVC
MVVMを見て、MVC系はPDSを各プラットフォームの特性に合わせて実現するものだと考えれば、他のMVC系の理解もサクサク進みます。 例えばASP.NET MVCはWebアプリケーションプラットフォーム Webプラットフォームである以上、HTMLのレンダリング(ASP.NET MVCの場合はRazorというDSLを使う)、セッション管理、遷移管理などの機能を持ちます。

48 MVVMパターンとMVC系パターン おまけ)ASP.NET MVCとMVC
しかしRazorがサポートするのは、単一ページのレンダリングであり、Webでは複雑になりがちな遷移管理などその他のViewプラットフォームの都合を請け負う部分が必要です。 ASP.NET MVCのRazor以外の、GUIプラットフォーム都合部分(主に遷移など)を請け負うのがASP.NET MVCでのControllerです。 もちろんViewとModelの間のデータの橋渡しもします。

49 MVVMパターンとMVC系パターン おまけ)ASP.NET MVCとMVC
なんで違うの?

50 MVVMパターンとMVC系パターン おまけ)ASP.NET MVCとMVC
MVC系が「Viewプラットフォームの特徴を生かしたPDS実現パターン」だという事を思い出しましょう。 つまり、プレゼンテーションプラットフォームが変わMVC系は変わるのです。 このサイクルを 繰り返す

51 MVVMパターンとMVC系パターン おまけ)ASP.NET MVCとMVC

52 MVVMパターンとMVC系パターン まとめ
MVVMパターンを含むMVC系パターンはPDSを実現するためのもの。 Presentation側が特にDSLを使用する場合などは、そのDSLの我儘などを担う部分が必要となってくる。

53 MVVMパターンとMVC系パターン まとめ
MV○パターンの○は全てPDSのPresentation側で、Viewで処理できないPresentationPlatformの我儘を担う。 MVVMのViewModel – XAMLのための状態ストア MVCのController – Razorで処理できないASP.NET MVC固有部分 少なくとも国内ではそういう情報がほとんどない=少なくとも日本語ではそういった説明はほとんどないものの、実は元のマーチンファウラーのPDSの説明に該当箇所がある。(海外でも誤解している人が多い事は、MOVE絡みで把握)

54 MVVMパターンとMVC系パターン まとめ
This principle is the most prominent part of Model View Controller (MVC), indeed for many people MVC is how they describe this separation. PresentationDomainSeparation – Martin Fowler この原則は、モデル・ビュー・コントローラー(MVC)の最も有名な個所です。確かに、多くのひとにとってMVCとは、この分断をどのように行うかというものとなっています。 プレゼンテーションとドメインの分離 – MartinFowler’s Bliki in Japanse

55 MVVMパターンとMVC系パターン まとめ
MV○系パターンではModelの中の設計にタッチしない。MVC系はPresentation固有の知識にあたる部分とそれ以外を分離するための知識である。 導出フェーズ終わり

56 MVC系の有効範囲 4.MVC系パターンの学習方法

57 MVC系パターンの学習方法 サンプルコードから学ぶ
結論から言うと概念を流し読みして理解が十分でない状態でサンプルからきちんとした概念を読みだそうとしても無駄です。 何故ならMVC系パターンは「楽に開発するために」あくまでもPDSに付随するメリットを手にいれるための手段なので、例えばModelの中の設計にタッチしていないわけで、サンプルコードにはその他の概念が含まれすぎています。 何種類か見てみましょう。

58 MVC系パターンの学習方法 責務に厳密な小規模なサンプル
例えば計算機レベルのサンプル 厳密に3つの責務にわけた所で、PDSの冗長さが目立つだけです。きちんと理論から到達したなら、PDSのメリットと冗長さというデメリットを比較して大抵こうはなりません。 サンプルとしての意図でこうなっているんでしょうが、その割にはメリットも伝えられません。

59 MVC系パターンの学習方法 適切に設計された小規模なサンプル
例えば計算機レベルのサンプル ViewModelをModelと統合しています。 計算機程度の小規模であるならば、大抵の場合あるべき姿です。でもこの姿からMVVMの姿って学べませんよね。

60 MVC系パターンの学習方法 大規模なサンプル

61 MVC系パターンの学習方法 マーケティングサンプル①
例えばSilverlightのWCF RIA Service。 普通に考えればそれだけ使えばModel部分を全部代替できるというものではないのですが、 そういう代替できるシナリオをわざわざ用意したり、ViewModelの責務に微妙にModelが染み出したようなサンプルがMSさんの物には多いです。 マーケマーケ。仕方ないとは思います。。。

62 MVC系パターンの学習方法 マーケティングサンプル②
例えばASP.NET MVC3のスキャフォールディング。 ControllerからDBいぢれたりしちゃいます。 PresentationPlatformはその進化の過程で”定型シナリオに簡単に対応するために”PDSを部分的に崩しすような機能を盛り込んできる事があります。 そしてこれが搭載されたMSさんが出してるようなASP.NET MVC3のサンプルは必然的にこの機能アピールが多くてつまりほとんどPDSが崩れているという。 でもCodePlexにあがっているような規模の大きいサンプルで(Project Silkとか)では使っていないみたいですよ。PDSを崩すデメリットが大きくなるからでしょう。

63 MVC系パターンの学習方法 サンプルからMVVMの最大公約数を見つける旅
ここから概念を抽出?・・・。 × Model内の設計 ドメインロジックパターン だけでも TransactionScript DomainModel TableModule (次のセッションで詳しく) etc

64 MVC系パターンの学習方法 サンプルからMVVMの最大公約数を見つける旅
ViewModelではコマンドを使う コードビハインドを書かない などと言った実装上の選択にすぎない事をMVVMの定義と紐づけます。しかしそれはやはりMVVMの定義とは関係がないものです。 そういった実装要素は、メリットとデメリットをしっかり見極めてご自身で状況によって取捨選択してください。 サンプルでの学習は概念の理解を前提としてそういった時に有用です。

65 MVC系パターンの学習方法 サンプルからMVVMの最大公約数を見つける旅
結論:いきなりサンプルからは無理なので横着しないできちんと概念から学びましょう。サンプルで学べるのはMVC系の考え方ではなくMVC系フレームワークの使い方程度です。 そしてそうやって学んだ使い方では、もともとMVC系の責務分割の目的がわからないものだからその実装要素が何の目的に寄与しているかわからない、結果実装要素の取捨選択ができない。 コマンド使うのがMVVMだよね? コードビハインド使わないのがMVVMだよね? どちらも違います

66 MVC系パターンの学習方法 サンプルからMVVMの最大公約数を見つける旅
もしPDSを踏まえてMVVMを理解していたらどうなるか? ViewModelは「Viewの何の我儘を請け負っているのか」に頭が回るようになりますし、そうなればViewModelはViewの状態を受け持つという事もわかります。そしてPDSの観点からViewModelに含めるべきではないコードが明確になります。 コマンドはコードビハインドを使わないっていうのは?

67 MVC系パターンの学習方法 サンプルからMVVMの最大公約数を見つける旅
そう、何一つトップダウンな決めつけなしできちんとPDSから各プラットフォーム用のMVC系をボトムアップで理解していけば、コマンドの使用やコードビハインドを使わないという知識は、XAMLとMVVMの組み合わせが可能にするViewの抽象化要件やデザイナとの分業要件のためにある事がわかるはずです。 ならViewの差し替え・抽象化要件がなかったら? コマンドを使わなくても良いし、コードビハインドを書きまくれば良いと判断できます。 MVVMの責務分割の根拠となるPDSの不理解こそがMVVMを教条主義に変えるものです。

68 MVC系パターンの学習方法 サンプルコードから学んだつもりになっても学べないのは当たり前です。きちんと概念 – それが責務分割であるMVC系ではその責務分割の根拠となるPDSからしっかりと理解すればさまざまな事がわかってきます。 まだ世の中に出て間もない新しいものは、そのプラットフォームの特徴を見極め、先ほどMVVMを導き出したように自分で検討してみるのもいいかもしれません。 そしたら周知してくださいね!

69 3.MVVMパターンとMVC系パターン おまけ)MVC系の適用?則る?遵守?考慮?

70 おまけ)MVC系の 適用?則る?遵守?考慮?
実は今回お話したMVVMの定義は簡略系です。 MVVMの先祖にPresentationModelパターンというMVC系のパターンがあります。

71 おまけ)MVC系の 適用?則る?遵守?考慮?
同じに見えませんか? ええ、MVVMパターンはPresentationModelパターンに加えViewの抽象化要件やデザイナとの分業などを可能にしているだけにすぎません。

72 おまけ)MVC系の 適用?則る?遵守?考慮?
その気になればViewを完全にXAMLの定義だけで構築することが可能な事や、Viewの抽象化に対応できること(コマンド/コードビハインドの使用生むなど)がPresentationModelパターン一般に想定されていないXAML系MVVM特有のメリットを生んでいます。 では今まで説明したMVVMの定義で組んだアプリケーションはPresentationModelを適用したのであって、MVVMを適用したのではないのか?

73 おまけ)MVC系の 適用?則る?遵守?考慮?
そうではありません。紛れもなくXAML系の都合とPDSを考慮 = MVVMパターンを考慮し、開発されたアプリケーションとなります。 MVVMパターンがもたらすメリットのうち、Viewの抽象化要件やデザイナとの分業は多くのケースでは不要だから、それに関わる部分を選択しなかっただけですね。そして不要な部分はメリットが無くてデメリット(冗長さ)があるだけなのだから採用しない、それこそがまさに適切なMVVMパターンの適用法です。

74 おまけ)MVC系の 適用?則る?遵守?考慮?
こうやってMVVMの責務分割/その根拠となるPDSから理解していればこういう取捨選択が可能になり、結果それがMVVMの典型的な実装になっていなくても、それは紛れもなくMVVMの適用結果として適切な実装(パターンを使用してメリットを享受)だし、MVVMを考慮した結果と言えます。 これがMVVMなんだ!などという実装は存在しないし、則るだとか遵守だとかいう表現はそもそも不適切です。 そういった表現はMVVMを実装例から学べたつもりになっている人に特有の表現なので気を付けましょう。そしてメリットを理解できていない実装に縛られているせいでMVVMを教条主義だと貶めるのも彼らです。惑わされないように。

75 適用TIPS 5.MVC系パターンの適用Tips

76 適用Tips ここでは前章までに培った知見を使って世の中で言われがちな様々な課題を確認していきます。 理解度確認に一緒に考えていきましょう。
MVVMを基準で話します。

77 適用Tips Q.Modelはデータの入れ物? A.データの入れ物だとしたら値をつめるのはViewModelしかなくなりますよね。PDSは?
意図的に崩したのでないのであれば×。他のMVC系でも同様

78 適用Tips Q.ModelはEntityFrameworkとかRIA Service?

79 適用Tips Q.MVC系パターンをつかえば、Domainを共有できるはずだから例えばASP.NET MVCとWPFでModelを共有出来たりするんでしょうか? A.ドメインという言葉に惑わされすぎです。 Modelは「PresentationPlatformと関係がない領域」です。 同じドメイン(問題領域)を解決するアプリを目指す以上、WebとリッチクライアントほどPresentationPlatformがあまりにも違えば当然「それ以外」であるModelも変わってきます。無論部分的には共有できますが。× 次のセッションで詳しくやりましょう。

80 まとめ 6.まとめ

81 まとめ PDSとは? PDSとは、アプリケーションを「プレゼンテーションに関わる部分」と「それ以外」に分ける考え方。
プレゼンテーションに関わる部分とは PresentationPlatformのGUI構築部分(XAMLなどのDSLとコードビハインドなど) PresentationPlatformの我儘に付き合う部分

82 まとめ MVC系パターンとは? MVC系パターンは、
プラットフォームの特徴をいかしてPDSを実現する事によりOOPのメリットとなる適切な責務分割や関心の分離が行え結果 保守性 変更容易性 大規模では開発生産性 などが確保できるもの。 その成り立ちからModelの内部の設計に関知しません。Modelの内部については別途検討が必要です。 すなわち当然の事ですがMVC系パターンは設計をアウトプットするための1要素でしかありません。

83 まとめ MVC系パターンとは? MVVMであれば、ViewとViewModelの責務は決定的です。よく
「今考えている処理をViewModelとModelのどちらに書けばいいかわからない」 という話を耳にしますが、 それはModelが曖昧な上にViewModelを橋渡しとしか思っていないからです

84 まとめ MVC系パターンとは? 真ん中にいるViewModelやControllerが必要以上に責務を負う事は、橋渡しもするからこそどんどん肥大する可能性があり危険なのです。 PDSを確保したいなら、ViewModelやControllerは極力薄くなるようにするべきです。欲しい機能はModel、あるいはViewのコントロールに持たせていきましょう。 あのControllerやPresenterやViewModelをも全て一言でくくる事になり何の説明にもなっていない真ん中橋渡し論は本当に罪深いものです。 しかし世間はそういった認識にあふれています。惑わされないようにしてください。

85 まとめ MVC系パターンとは? 楽をするためには時にはPDSで得られるメリットとデメリットを測りにかけて、PDSを崩すことも大事です。

86 ご清聴ありがとうございました!


Download ppt "GUIアーキテクチャ・パターンの基礎から MVVMパターンへ"

Similar presentations


Ads by Google