カウンター付き SNS シェアボタン まとめ
サンプルとして表示しているボタンは実際のボタンを使っています。 対象はこのブログのトップページになっているので、 よければ押してください。
- 共通
- Twitter - ツイートボタン
- Facebook - いいね(Like)ボタン
- Google+1
- mixi - イイネボタン
- はてなブックマーク
- ShareThis
共通
ボタンを設置する場合には、基本的に以下の手順になります。- ボタン作成用のページにいって、コードを取得
- 表示したいページ(FC2 ブログではテンプレート)にそのコードを張り付け
コードの多くは 2 つの部分に分けられます。
- ボタンの表示部
- スクリプト部
どちらかは SNS によって変わります。 ただし、明示的に書かれていないものはどちらでも構わないものが多いです。
なお、Google+1 など一部のボタンは IE では勝手に改行が入ってしまう場合があります。
それらのボタンは inline ブロックという機能を使っており、 IE7 以前の古いバージョンの IE ではこの機能に対応していないためです。 新しいバージョンであっても、古い動作モードで動くと、改行が入ってしまいます。 対応策は以前の記事を見てください。
複数記事、 FC2 ブログ
FC2 ブログのように 1 ページに複数記事を表示することがあるタイプではいくつか注意点があります。
- スクリプト部はすべての記事の前または後
-
ボタンは記事ごとに指定しますが、スクリプト部は 1 ページに 1 箇所だけ記述します。
前または後のタイプかによって記述箇所が変わります。
タイプ 場所 前 ヘッダー部 <head> ~ </head>
ページの最初 (</body> の直後)後 ページの最後 (</body> の直前)
- URL とタイトルを指定する
-
ボタンのリンク対象となるページの URL とタイトルは
デフォルトではボタンを設定したページから自動で取得されます。
複数記事の場合は明示的にその対象を記事の個別記事のページにしておく必要があります。
ただし、 SNS によってはタイトルの指定がないものもあります。
指定の仕方について詳しくは最初の Twitter のボタンで説明します。
Twitter - ツイートボタン
ツイート対象記事の URL 含んだツイートの数を表示する Twitter のボタンです。
FC2 ブログでは Twitter と Facebook の「いいね! 」ボタンは設定で簡単につけられます。 しかし、他のボタンを付ける場合は広告が間に入って位置が揃わなくなるので、別途つけた方がいいでしょう。
1 ページ 1 記事であれば、下記リンクを開いてページ右の部分をコピーして張り付ければ、 使用できます。

複数記事
複数記事の場合は URL 、 タイトルに適当な値を入れておきます。後述する <%topentry_link> のようなコードを直接書くと <, > がエスケープされたり、エラーになったりする場合があります。
コード部分は 1 行目がボタン、 2 行目がスクリプト部となっています。
ボタンを各記事に設定します。この時適当に入れておいた URL 、タイトルを記事にあわせて変更します。
スクリプト部は前後どちらに置いても構わないのですが、 一応コードに合わせて、ページの最後( </body> の前)に記述しておきます。
FC2ブログ
FC2 ブログの場合は、スクリプト部は前節のようにページの最後に記述します。ボタンは各記事におくので、<!--topentry--> ブロック内に記述します。
この時 URL, タイトルを次のように変更します。
項目 | 記述 |
---|---|
URL | <%topentry_link> |
タイトル | <%topentry_title> | <%blog_name> |
FC2 ブログ用のコードのサンプルを以下に挙げておきます。
基本的にこのコードを張り付ければ、使えると思いますが、 時々コードが変わることもあるので、 SNS のサイトから取ってきた方が確実だと思います。
また、mixi のような SNS ボタンの一部は ID 番号を必要とします。 この番号は特に隠すものではないのですが、 そのままコピーして使えないように番号を XXXX で伏字にしています。
ボタン:
<a href="https://twitter.com/share" class="twitter-share-button" data-url="<%topentry_link>" data-text="<%topentry_title> | <%blog_name>" data-via="yohshiy" data-lang="ja">ツイート</a>スクリプト:
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
まとめると次の表のようになります。
項目 | 値 |
---|---|
作成ページ | Twitter / Twitter ボタン |
スクリプト部 | (後) |
タイトル指定 | あり |
ID 番号 | なし |
Facebook - いいね(Like)ボタン
Facebook の 「いいね! 」ボタンです。 こちらも Twitter 同様、 FC2 ブログでは設定で追加することができます。
ただ、その場合も OGP の設定はしておいた方がいいと思います。
項目 | 値 |
---|---|
作成ページ | Like Button - Facebook 開発者 |
スクリプト部 | [HTML5] <body>のすぐ後 [IFRAME] 一体型 |
タイトル指定 | なし |
ID 番号 | なし |


「いいね! 」ボタンの場合には、 HTML5 タイプ、 iframe タイプなどコードのタイプを選べます。 私としては iframe タイプが使い勝手がいいと思います。
iframe タイプの場合はボタンとスクリプト部は一緒になっています。
「いいね! 」ボタンでは URL の指定はありますが、タイトルの指定はありません。 また、 iframe の場合、 URL は省略できません。省略したい場合は HTML5 タイプなどを指定します。
[Send Button] は外しておきます。 それ以外は [Layout Style], [Width] 等を好みで変更します。
ボタン(スクリプト):
<iframe src="//www.facebook.com/plugins/like.php?href=<%topentry_enc_link>&send=false&layout=button_count&width=450&show_faces=false&action=like&colorscheme=light&font&height=22" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:105px; height:21px;" allowTransparency="true"> </iframe>iframe タイプの場合、 対象の URL は GET メソッドの引数として渡すため、 URL エンコードされた <%topentry_enc_link> を使います。
OGP
「いいね! 」作成用のページでは、 Step 1 の後に Step 2 があります。 これは OGT または OGP と呼ばれる SNS 用の情報を設定するためのものです。 これを設定していないと次のような問題があります。- 「いいね! 」を押してもウオールに上がらない
- シェア時の画像としてい適当なものが使われてしまう
また、 OGP は Facebook だけでなく、 mixi, Google+ など他の SNS でも利用されます。
ただし、この OGP はヘッダー部記述するため、 複数記事表示の場合には 「いいね! 」の対象と完全に合わせることはできません。
設定する場合は Step 2 に進み、値を入力してコードを取得します。

項目 | 説明 |
---|---|
Title | 記事のタイトル |
Type | 記事の場合は article。 ブログのトップページでは blog |
Image | リンク時に使用する画像の URL 。 200x200 以上のサイズにしておいた方がいいです。 |
Site name | サイト名 |
Admin | Facebook の ID 番号。 ページを表示した際に自動で設定されます。 |
ここでは 個別記事モード でのみ全ての項目を設定し、 それ以外のモードではブログで共通の部分だけ指定するようにしています。
また サンプルの ID 名の部分は伏字にしています。
<meta property="og:image" content="<%image>" /> <meta property="og:site_name" content="<%blog_name>" /> <meta property="fb:admins" content="XXXXXXXXXXXXXXX" /> <meta property="og:type" content="article" /> <!--permanent_area--> <!--topentry--> <meta property="og:title" content="<%topentry_title> | <%blog_name>" /> <meta property="og:url" content="<%topentry_link>" /> <!--/topentry--> <!--/permanent_area-->OGP の追加後、以下のページで OGP がちゃんと設定されているかチェックすることができます。
Google+1
Google の作った SNS である Google+ のシェアボタンです。
項目 | 値 |
---|---|
作成ページ | +1 ボタン - Google+ Platform ? Google Developers |
スクリプト部 | 後 |
タイトル指定 | なし |
ID 番号 | なし |

URL を指定する場合は [詳細オプション] を開いて設定します。
ボタン:
<div class="g-plusone" data-size="medium" data-href="<%topentry_link>"></div>スクリプト:
<script type="text/javascript"> window.___gcfg = {lang: 'ja'}; (function() { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/plusone.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })(); </script>
mixi - イイネボタン
mixi は日本ではシェアの広い SNS です。 mixi チェック程見かけませんが、 実は mixi にも Facebook のような 「イイネ!」ボタンがあります。
項目 | 値 |
---|---|
作成ページ | --- |
スクリプト部 | (後) |
タイトル指定 | なし |
ID 番号 | あり |
項目 | 入力情報 |
---|---|
サービス名 | 任意の文字でかまいません。"イイネ!ボタンコード取得" など |
サービスの URL | こちらもなんでもいいのですが、 ブログのトップページといったサイトの URL を入力します。 |

ボタン:
<div data-plugins-type="mixi-favorite" data-service-key="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" data-size="medium" data-href="<%topentry_link>" data-show-faces="false" data-show-count="true" data-show-comment="true" data-width="100px"> </div>スクリプト:
<script type="text/javascript">(function(d) {var s = d.createElement('script'); s.type = 'text/javascript'; s.async = true;s.src = '//static.mixi.jp/js/plugins.js#lang=ja';d.getElementsByTagName('head')[0].appendChild(s);})(document);</script>
はてなブックマーク



はてなブックマークはソーシャルブックマークと呼ばれる ブックマークをシェアする SNS です。
ソーシャルブックマークに関しては以前の記事を見てください。
項目 | 値 |
---|---|
作成ページ | はてなブックマークボタンの作成・設置について |
スクリプト部 | (後) |
タイトル指定 | あり |
ID 番号 | なし |
<a href="http://b.hatena.ne.jp/entry/<%topentry_link>" class="hatena-bookmark-button" data-hatena-bookmark-title="<%topentry_title> | <%blog_name>" data-hatena-bookmark-layout="simple-balloon" title="このエントリーをはてなブックマークに追加"> <img src="http://b.st-hatena.com/images/entry-button/button-only.gif" alt="このエントリーをはてなブックマークに追加" width="20" height="20" style="border: none;" /> </a>スクリプト :
<script type="text/javascript" src="http://b.st-hatena.com/js/bookmark_button.js" charset="utf-8" async="async"></script>
LinkedIn はビジネス系の SNS です。
日本ではまだそれほどでは広まっていない気がしますが、 海外ではかなりシェアの広い SNS です。
基本的に転職用の売り込みや会社側からの検索を目的とした SNS なので、 転職当たり前のアメリカで広まるのはわかるのですが、日本ではどうかなという気もします。 ただ、転職専用というわけでもないですし、押さえておく価値はあるのではないかと思います。
項目 | 値 |
---|---|
作成ページ | Share Plugin Generator | LinkedIn Developer Network |
スクリプト部 | (前) |
タイトル指定 | なし |
ID 番号 | なし |

スクリプト :
<script src="//platform.linkedin.com/in.js" type="text/javascript"></script>ボタン :
<script type="IN/Share" data-url="<%topentry_link>" data-counter="right"></script>
Reddit はニュース記事などの投票式の SNS です。 LinkedIn 同様、海外でよく使われている SNS の一つです。
「いいね! 」のようなライトコミュニケーションでは、 よければチェックして、そうでなければ何もしないというのが普通です。 この Reddit はマイナスへの投票ができることがの特徴です。
似たような SNS として Digg も有名ですが、残念ながらこちらは日本語用ページがありません。
Reddit は対象が記事専門のような感じなので、 Reddit のボタンサンプルだけはトップページではなく、 この記事を対象としています。
項目 | 値 |
---|---|
作成ページ | japan: reddit用ボタン |
スクリプト部 | 一体型 |
タイトル指定 | なし (インタラクティブ型はあり) |
ID 番号 | なし |

Reddit にはコード取得用の入力フォームはありません。 [view code] を選択して、コードを表示し、それをコピーします。
複数記事の場合にはリンクの URL の引数として対象の URL を指定します。 ここでの値は URL エスケープをしておく必要があります。
サンプル :
<script type="text/javascript" src="http://www.reddit.com/buttonlite.js?i=1&url=http%3A%2F%2Fyohshiy.blog.fc2.com%2Fblog-entry-161.html"></script>
FC2ブログの場合には <%topentry_enc_link> が URL エスケープされたリンクとなります。 また、以下のサンプルでは選択時に新しいウィンドウ(タブ)で表示する newwindow=1 も指定しています。
ボタン(スクリプト) :
<script type="text/javascript" src="http://www.reddit.com/buttonlite.js?i=1&newwindow=1&url=<%topentry_enc_link>"></script>
インタラクティブボタン
カウンターだけでなく、ポイントの上下ができるボタンもあります。
ただし、こちらの場合は URL 等を JavaScript の変数として指定するため、 複数記事の場合には使えません。
(使えるのかもしれませんが、変数がどの位有効なのかよくわからないので、 使わない方が無難だと思います)
使用可能な変数は以下のものです。
変数 | 説明 |
---|---|
reddit_target='[COMMUNITY]' | コミュニティーの指定 日本語のコミュニティーは ja です |
reddit_title='[TITLE]' | タイトルの指定 |
reddit_newwindow='1' | リンクを新しいウィンドウで表示する |
reddit_bgcolor='[COLOR]' | 背景色の指定 |
reddit_bordercolor='[COLOR]' | 境界線の色の指定 |
<script type="text/javascript"> <!-- 変数の設定 --> reddit_url = "http://www.reddit.com/buttons"; reddit_title = "Buttons!"; reddit_bgcolor = "FF3"; reddit_bordercolor = "00F"; reddit_newwindow='1'; reddit_target='ja' </script> <!-- ボタン(スクリプト) --> <script type="text/javascript" src="http://www.reddit.com/static/button/button3.js"></script>
FC2 ブログで個別記事モードの場合はインタラクティブボタン、 その他のモードではカウンター付きシェアボタンとする場合には次のようになります。
<!--not_permanent_area--> <script type="text/javascript" src="http://www.reddit.com/buttonlite.js?i=2&newwindow=1&url=<%topentry_enc_link>"></script> <!--/not_permanent_area--> <!--permanent_area--> <script type="text/javascript"> reddit_url = "<%topentry_link>"; reddit_title = "<%topentry_title> | <%blog_name>"; reddit_newwindow='1'; reddit_target='ja' </script> <script type="text/javascript" src="http://www.reddit.com/static/button/button1.js"></script> <!--/permanent_area-->ただし、カウンター付きのボタンの場合はタイトルが指定できないので、 Reddit のボタンよりむしろ次項の ShareThis の方がいいのではないかと思います。
ShareThis
最後にいろいろな SNS のシェアボタンをまとめるタイプのサービスとして ShareThis を紹介します。
シェアボタンのまとめ系のサービスは結構あるのですが、 ShareThis はカウンター付きボタンの対応 SNS が圧倒的に多いです。
今まで紹介してきた SNS も mixi 以外は対応しています。
Tumblr や Delicious といったカウンター付きのボタンがない SNS でさえ独自の集計で対応しています。
ただし、独自の集計をしているせいか SNS の提供しているカウンター付きボタンと一致しないこともあります。
項目 | 値 |
---|---|
作成ページ | ShareThis Sharing Button |
スクリプト部 | 前(ヘッダー部) |
タイトル指定 | あり |
ID 番号 | あり |
- Step 1. Platform
- Website を選択します。
タグまたは下部のリンクで次のステップに移動します。
- Step 2. Style
- 使いたいスタイルを選択します。
- Step 3. Customization
- Drag & Drop で SNS ボタンの追加や並び替えを行います。
[Sharing Buttons] が ShareThis の用意した シェアボタンです。
[Other Social Plugins] は 「いいね!(Like)」 や Google+1 のようなボタンをそのまま使うタイプのものです。
- Get the Code
- ShareThis 自身のボタンのタイプを選択し、コードを取得します。
ShareThis 自身のボタンはいろいろな SNS にシェアできるポップアップを表示します。 表示されているカウンター値は他の SNS のシェアのカウントを合計したものです。
ボタンはそのままでは現在のページが対象となってしまうので、 複数記事の場合には対象のタイトルや URL を指定するための属性(st_title, st_url)をボタンごとに追加する必要があります。
スクリプト :
<script type="text/javascript">var switchTo5x=true;</script> <script type="text/javascript" src="http://w.sharethis.com/button/buttons.js"></script> <script type="text/javascript">stLight.options({publisher: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"}); </script>ボタン :
<span class='st_delicious_hcount' displayText='Delicious' st_title="<%topentry_title> | <%blog_name>" st_url="<%topentry_link>"></span> <span class='st_tumblr_hcount' displayText='Tumblr' st_title="<%topentry_title> | <%blog_name>" st_url="<%topentry_link>"></span> <span class='st_linkedin_hcount' displayText='LinkedIn' st_title="<%topentry_title> | <%blog_name>" st_url="<%topentry_link>"></span> <span class='st_sharethis_hcount' displayText='ShareThis' st_title="<%topentry_title> | <%blog_name>" st_url="<%topentry_link>"></span>
なお、スクリプト部は他のスタイルと共通になっています。 そのため、他のスタイルを混在させてページに表示することも可能です。
このブログでもカウンター付きのボタンを記事ごとに表示し、 右上にはトップページやカテゴリー記事用に現在のページが対象となるシャアボタンをつけています。
雑把の UI アーキテクチャー史(MVCからMVVMへ)
今回は UI アーキテクチャーの歴史についてです。
もともとスライドだったのですが、 説明を追加して、記事にしてみました。最初は MVVM の簡単な説明のつもりでしたが、 MVC とその問題点を付けて、 最近の UI 開発の傾向を書いて、とやっているうちに変に広がった内容になってます。
スライド版はこちらです。
ここからブログ版です。
目次
- MVC 以前
- MVC - 拡張 MVC 時代
- MVVM(.NET)
- .NET 以外の傾向
MVC 以前
最初に MVC 以前の状態とともに UI アーキテクチャーにおける前提ついてお話します。UI アーキテクチャーの大前提
MVC 以降いろいろな UI アーキテクチャーが登場しますが、 共通している目的は アプリケーションのコア部分と UI 部分を分離する ということです。これはかっこよく言うと、次のようになります。
ビジネスロジックとプレゼンテーションロジックを分割する
MVC 以前ではそれらを 1 つのオブジェクトにまとめる傾向があったらしいです。
MVC 自体は賛否両論あるかも知れませんが、 そういった考えが広まり、 UI アーキテクチャーが注目されるきっかけとなったことは 大きな意味があると思います。
もう一つ最初に伝えておくべきことは 完璧な UI アーキテクチャーはない ということです。
銀の弾丸などないという格言があります。
ソフトウェア開発では、魔法のように問題を解決するような技術は存在しないことを示唆する言葉です。 これは UI アーキテクチャーでも同様です。
そのため、最後に出てきた UI アーキテクチャーでも決定版とはなりません。
問題がでてきて、新しいものが生まれるという繰り返しが今後も続いていくでしょう。
MVC と 拡張 MVC
MVC (GoF 本)
MVC が広くつかわれるようになったのは、 『 GoF 本』 で紹介されたことが大きかったでしょう。そこで、『 GoF 本』 での MVC から始めることにします。

モジュール | 説明 |
---|---|
Model | アプリケーションオブジェクト、データ管理 |
View | 画面の表現 |
Controller | ユーザー入力に対するインターフェース |
もう少しわかりやすいように Wikipedia にあったシナリオをコラボレーション図風にしました。

今までの説明で MVC は理解できたでしょうか ?
Model 、 View の方はわりとわかりやすいと思います。
しかし、 Controller はわかりづらいです。
ユーザー入力に対するインターフェースといわれても、 "View に入るんじゃないの ?" と思う人も多いでしょう。
また、ちゃんと理解できたとしても、"もっといい方法があるんじゃないか" と指摘したい点も多々あるんじゃないでしょうか。
例えば、 私は Model から View へ矢印がでているのは、結合が密になりよくないと思います。
誤解されたり、改良されたりで、 MVC は人によって解釈が様々になってしまっているのが現状です。
MVC が何を指しているのか、はっきり言って正解はわかりません。
今度は、この変化していった Web、 PC での MVC について見ていきます。
MVC (Web)
Web サービスで広く使われている MVC フレームワークとして Ruby on Rails があります。 これは次のようなアーキテクチャーです。
モジュール | 説明 |
---|---|
Model | DB へのアクセス |
View | html ページと html ページの作成 |
Controller | 入力の受け取り。他のモジュールの操作 |
View は html ページとその作成を担当します。 CGI は アドレスとパラメーター(アドレスの ? の後など)を受け取り、処理を行います。 その受け取り部分が Controller です。
Model と View ではなく、なぜ MVC としたのでしょうか ?
『 GoF 本』 では Controller を分ける利点をいくつか挙げられています。
- キーボードの応答を変えたり、メニューからの呼び出しに変更するとき、表示方法を変更しなくていい。
- 入力イベントを無視するといったことをコントローラーのインスタンスの入れ替えで可能。
ちょっと無理そうな話ですが、例えば、 PC アプリが次のような構成であれば、 入れ替えて使うということができるかも知れません。

ただし、アプリが複雑化してくると、すぐ厳しくなってくるはずです。
やはり、これは欲張りすぎというものでしょう。
拡張 MVC (PC アプリ)
次に PC 上で動作するデスクトップアプリケーションの場合です。この場合は、 Widget や Control といった GUI ツールキットが提供する部品を組み合わせて作成します。
高機能な部品になってくると、どうしても表示と入力処理を兼ね合わせるものになってしまいます。 このため、 View と Controller の分離は不可能になってきます。
『 GoF 本』 で指摘されている機能はほとんど GUI 部品の方で機能を持っていますし、 普通は PC 向けだけに作るので、あまり Controller を分ける必要もありません。
そこで、でてきたのが V と C をまとめて View とする拡張 MVC です。 (拡張といいつつ、減っていますが...)
これは、コアと UI 分離という基本原則だけ残った形です。

拡張 MVC は GUI ツールキットによっては次のような呼ばれ方もします。
- MFC : Document - View
- Qt : Model - View
問題点
次のような状態でしばし落ち着きます。対象 | UI アーキテクチャー |
---|---|
PC | 拡張 MVC (MV) |
Web | MVC |
ただし、 拡張 MVC に問題がないわけではありません。
それは View の肥大化 です。
もともと大して分けてないので、 プログラムの 8, 9 割が View というのも珍しくありません。
ちゃんと意識して作らないと、全部 View で MVC 以前に戻ることもありえます。
そこで、"なんとか分けなきゃ" となります。
一方、 Web は Web で Google の Web アプリのような高機能なものが求められ、 JavaScript が大規模化し、 こちらも View の肥大化が起こります。
UI アーキテクチャーの乱立
問題点の解決ためにいろいろな UI アーキテクチャーが考案されます。- MVP - Model, View, Presenter
- PM - プレゼンテーションモデル
- アプリケーションモデル
例えば、 MVP の Presenter は簡単にいうと M と V の "つなぎ" の役割ですが、 Controller の名前でそのように使われることもあります。
また、 こういった UI アーキテクチャーは GUI ツールキットなどで、 フレームワークとして提供されないとなかなか定着しづらいものです。
要望
新たな要望も出てきます。これはデザインの重要性が高まりからきています。
Web サイトは大手企業などでは Web デザイナーが作成しています。 それと同じように画面デザインもデザイナーに任せたいという要望です。
しかし、そのためには 画面レイアウトとコードを分離する必要が出てきます。
ただ、これは GUI ビルダーでも、昔から試行錯誤されているところなので、古くからの要求ともいえます。
画面レイアウト、コード分離の難点
GUI アプリケーションでは必然的にイベント駆動プログラミングとなります。これが分離のネックです。
イベント駆動では呼び方はいろいろありますが、基本的に次のような仕組みです。
- シグナル(イベント) → コールバック

- ループで画面を表示
- イベント発生(ボタンクリックなど)
- コールバック関数が呼ばれ、処理を実行
- ループに戻る
MVVM(.NET)
問題点の解決のため、 .NET では MVVM が使わるようになってきました。.NET の登場
- Win32API と MFC
- Java の台頭
- C#、.NET で対抗
Windows での GUI のベースは C 用の Win32API です。
.NET 登場以前は VC++ では API をラップした MFC が使われていました。 C のラッパーなので、オブジェクト指向でできていないとか、 C++ でしか使えないといった批判がありました。
2.
そんな中 Java が出て来ました。
Java はガベージコレクションなどの機能で C++ よりも開発しやすく、しかもクロスプラットフォームです。
また、 Linux も gnome や KDE などで使いやすくなってきていました。
アプリケーション開発をみんな Java に移行され、 そのアプリが OS を選ばずに動作するとなれば、 開発ツールだけでなく、 Windows からユーザーをごっそり持っていかれる危険性が出てきます。
3.
そこで MS が対抗して出したのが C# と .NET です。
ただし、そこで最初に用意された Form は従来の部品を .NET 用にラップしたもので、 ピュア .NET ではありませんでした。
『 6 つの UI アーキテクチャ・パターン』での紹介では
フォームとコントロールですが、これはまだ拡張 MVC のままといってもいいでしょう。
WPF
その後、.NET 用に作りなおされた GUI ツールキットとして登場したのが、 WPF です。しかし、なかなか広まっていないのが現状です。
おそらく、原因は次のようなところでしょう。
- Form の方が部品が多機能で豊富
- 従来の部品を使っているからこそ、今までの蓄積分があり、 WPF の部品が貧相に見えてしまいます。
- 使い方がわかりづらい
- WPF では VS で部品を配置した後、ハタと次どうすればいいかわからなくなってしまいます。
Form の方が使い方は想像しやすいです。
また、使っている人が少ない → いいドキュメントも少ない ということもあります。
- WPF では VS で部品を配置した後、ハタと次どうすればいいかわからなくなってしまいます。
Form の方が使い方は想像しやすいです。
- 長い間 MS 製品ですら使われなかった
- 「さぁ、使ってください」と出された WPF ですが、
使う場合には「本当に実用に耐えうるの ? 」 というのは気になるところです。
そんな中、 MS 自身が自分のところの開発に使っていないとなると「大丈夫かこれ。」と思うのは当然でしょう。
- 「さぁ、使ってください」と出された WPF ですが、
使う場合には「本当に実用に耐えうるの ? 」 というのは気になるところです。
MVVM の登場
WPF はなかなか使われません。 しかし、だからといって Form のままでは問題点と要望が解決できません。- View の肥大化
- 画面レイアウトとコードの分離
流れとしては MVP → PM → MVVM といった感じです。 と、その前に採用されている技術を紹介しましょう。
- データバインディング
- コマンドパターン
データバインディング
今更ですが、データを扱う部分は Data や Core ではなく、 何故 Model というのでしょうか ?ここでの Model の意味はモデル化、モデリングといった時と同じで抽象化の意味です。
データは XML ファイルや DB などですが、これをプログラム内では扱いやすい構造体(オブジェクト)などに変換して使います。 データそのものではなく、構造体などに抽象化しているところなので、 Model です。

デスクトップアプリでは、 Model 内でデータを構造体(オブジェクト)として直接管理することもありますが、 多くはファイル、 DB から構造体(オブジェクト)に変換する必要があります。
この技術をデータバインディング といいます。
ただ、 プログラミング言語にメタプログラミング(リフレクション)の機能が必要だったり、 C++ のようにそれがない言語では特殊な前処理が必要だったりとそうそう簡単にできるものでもありません。
設定画面でよくあるパターン
『 GoF 本』にでてくるようなパターンではありませんが、 設定画面などでよく使われる手法があります。それは画面の内容と構造体(オブジェクト)との相互に変換する機能を持たせることです。
デフォルト値があったり、部品の値がそのまま確定ではないモーダルなダイアログだったりする場合に向いています。

通常、この変換は自分で実装しないといけないのですが、 WPF ではこの実装を助ける機能があり、双方向データバインディングと呼ばれています。
これ、 Model で使われるものと似ていないでしょうか ?
画面(View)を構造体(オブジェクト)に変換することで、抽象化しています。 ViewModel の由来は View 用の Model というところからきています。
双方向データバインディングにより、 ViewModel のオブジェクトの値を変更すると画面が変更され、逆に画面を変更すると ViewModel の値が変わります。 画面を抽象化した ViewModel としておくことで、プレゼンテーションロジックのテストがやりやすくなります。
コマンドパターン
こちらは『 GoF 本』にもでてくるパターンです。要求をオブジェクトでカプセル化するパターンで、 いろいろなところからの呼び出しに対応しやすくなります。

MVVM
MVVM は次のような構成です。
画面レイアウトとコードの分離
- View
- XAML : XML でレイアウト定義
- ViewModel
-
- データ: 双方向バインディングで同期 (大部分をこれで行う)
- コマンド : 必要最小限のイベント駆動
これにより、 画面デザインは Expression Blend などのデザインツールで行えるようになります。
パラメーター項目の設定などはデータバンディングを使い、 [OK] ボタンを押すといった必要最小限だけイベント駆動にします。
これにより、なるべくコードと分離しています。
View の分割
拡張 MVC (MV) における View の部分を View と ViewModel に分割することで肥大化を軽減しています。ただ、 ViewModel がコマンドの管理だけならば、 Controller と区別しづらく、MVC に取り込まれていたかもしれません。
データバインドが MVVM の特徴です。
逆にデータバインドの機構がないと実装が大変なため、 MVVM は WPF 用の UI アーキテクチャー と言えます。
MVVM の実装
確かに MVVM は WPF 用の UI アーキテクチャーです。しかし、注意していただきたいのは、 WPF は MVVM フレームワークではないということです。
これは次のようなことを意味します。
- WPF で作れば MVVM になるわけではない
- MVVM のアーキテクチャーを崩さないよう意識して実装する必要がある
- MVVM を実装するには毎回同じようなコードを書く必要がある
(『 MVVM 入門 その4「ライブラリを使おう」 言語: C# Visual Studio 2010 用』)
.NET 以外の傾向
.NET 以外にも、最近の傾向について触れておきます。Web アプリケーション
問題のところで Web では JavaScript の部分が大規模化していると記述しました。この解決策としては、 JavaScript の部分もフレームワークを使うというものがあります。

よく使われるフレームワークは Backbone.js、 AngularJS といったもので、 MVC が主流のようです。
2 段構えになってややこしいですが、 JavaScript はセキュリティ上、サーバー側のアクセスには制約があり、仕方ないところでしょう。
ただ、 最近は Node.js などのサーバーサイド JavaScript もあり、 コードを共有化して減らすといった工夫もできます。
また、 JavaScript には "スクリプトのわりに書きづらい"、 "大規模開発に向いていない" といった欠点があります。このため、 変換系の新言語や Dart に移行するという流れもあります。 MVVM にはデータバインディングが必要と書きましたが、 実は Dart の UI パッケージにもデータバインディングの機能があります。
ただし、こちらは MDV(model-driven view) というアーキテクチャーを採用しているようです。
モバイル
スマホ、タブレットの出現により、 今までの PC 、 Web に加え、 モバイルという分野ができてきました。このモバイル用アプリは標準では次の言語で開発します。
OS | 言語 |
---|---|
iOS | Objective-C |
Android | Java |
しかし、 iOS 用のアプリを作ったら、 次は Android 版もというのが自然な流れです。
当然、ソースコードはなるべく共通化したいでしょう。
そのため、いろいろな言語での開発環境が出てきています。 注目されているのは、これだと思います。
HTML5 + JavaScriptJQuery Mobile や Titanium といったフレームワークがあります。
.NET 以外の PC アプリ
.NET 以外の PC アプリでも Mozilla の XUL、 Qt の QML のように 画面レイアウト定義に XML が使われる傾向があります。.NET と違うのは、これらは HTML のように JavaScript を使います。 JavaScript をにかわ(glue)言語として使う構成です。

対象 | 作成 |
---|---|
画面レイアウト | XML |
GUI 部品 | GUI ツールキットが提供(C++) |
アプリケーション全体 | JavaScript |
コア、スピードネック部分 | C++ |
今後、どうなる ?
Web アプリでは同一のソースを PC ブラウザー、スマホ、タブレットのそれぞれの画面にあわせて表示する レスポンシブ Web デザインという技術が注目されています。これはモバイルアプリでも必要な技術です。
HTML5 + JavaScriptで Web 、 モバイルは統一化される傾向があり、 実際 Titanium では、共通のソースで作成できるようです。
シェアはかなり小さいですが、 MS も Windows Phone というスマホ用の OS を出しています。
こちらの開発環境は PC 版から機能を削った SilverLight です。 SilverLight でも WPF と同様に MVVM が使えます。
Windows 8 のタッチパネル対応などもあり、 .NET では PC 、 モバイルの統一化の傾向が見受けられます。
モバイルの Titanium から派生した TideSDK では HTML5 + JavaScript といった Web の技術で PC アプリを開発できます。
こうやってみてくると Web 、 モバイル、 PC の開発が近づいてきているようです。
MVC の頃は PC と Web の共通化は無理と思ったものですが、 3 つの共通化が実現できる日がくるかも知れません。