カウンター付き SNS シェアボタン まとめ

Facebook の「いいね! 」ボタンのようなカウンター付き SNS シェアボタンの設置方法についてまとめてみました。

サンプルとして表示しているボタンは実際のボタンを使っています。 対象はこのブログのトップページになっているので、 よければ押してください。

共通

ボタンを設置する場合には、基本的に以下の手順になります。

  1. ボタン作成用のページにいって、コードを取得
  2. 表示したいページ(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 記事であれば、下記リンクを開いてページ右の部分をコピーして張り付ければ、 使用できます。 Twitter

複数記事

複数記事の場合は 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 番号 なし
Facebook Facebook code

「いいね! 」ボタンの場合には、 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>&amp;send=false&amp;layout=button_count&amp;width=450&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font&amp;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 用の情報を設定するためのものです。 これを設定していないと次のような問題があります。
  • 「いいね! 」を押してもウオールに上がらない
  • シェア時の画像としてい適当なものが使われてしまう
「いいね! 」だけでなく、 シェアやコメントなど Facebook 関連のブログパーツを使用する場合は設定しておいた方がいいと思います。
また、 OGP は Facebook だけでなく、 mixi, Google+ など他の SNS でも利用されます。

ただし、この OGP はヘッダー部記述するため、 複数記事表示の場合には 「いいね! 」の対象と完全に合わせることはできません。

設定する場合は Step 2 に進み、値を入力してコードを取得します。
Facebook OGP
項目 説明
Title 記事のタイトル
Type 記事の場合は article。 ブログのトップページでは blog
Image リンク時に使用する画像の URL 。
200x200 以上のサイズにしておいた方がいいです。
Site name サイト名
Admin Facebook の ID 番号。
ページを表示した際に自動で設定されます。
FC2 ブログでの設定例を挙げておきます。
ここでは 個別記事モード でのみ全ての項目を設定し、 それ以外のモードではブログで共通の部分だけ指定するようにしています。
また サンプルの 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 番号 なし
Google+1
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 を入力します。
Mixi 新規サービス登録

ボタン:
        <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



LinkedInビジネス系の SNS です。
日本ではまだそれほどでは広まっていない気がしますが、 海外ではかなりシェアの広い SNS です。
基本的に転職用の売り込みや会社側からの検索を目的とした SNS なので、 転職当たり前のアメリカで広まるのはわかるのですが、日本ではどうかなという気もします。 ただ、転職専用というわけでもないですし、押さえておく価値はあるのではないかと思います。

項目
作成ページ Share Plugin Generator | LinkedIn Developer Network
スクリプト部 (前)
タイトル指定 なし
ID 番号 なし
LinkedIn

スクリプト :
<script src="//platform.linkedin.com/in.js" type="text/javascript"></script>
ボタン :
<script type="IN/Share" data-url="<%topentry_link>" data-counter="right"></script>

Reddit



Reddit はニュース記事などの投票式の SNS です。 LinkedIn 同様、海外でよく使われている SNS の一つです。
「いいね! 」のようなライトコミュニケーションでは、 よければチェックして、そうでなければ何もしないというのが普通です。 この Reddit はマイナスへの投票ができることがの特徴です。

似たような SNS として Digg も有名ですが、残念ながらこちらは日本語用ページがありません。

Reddit は対象が記事専門のような感じなので、 Reddit のボタンサンプルだけはトップページではなく、 この記事を対象としています。
項目
作成ページ japan: reddit用ボタン
スクリプト部 一体型
タイトル指定 なし (インタラクティブ型はあり)
ID 番号 なし
Reddit
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>

インタラクティブボタン

カウンターだけでなく、ポイントの上下ができるボタンもあります。 Reddit interactive
ただし、こちらの場合は 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 を選択します。
タグまたは下部のリンクで次のステップに移動します。
ShareThis Step 1
Step 2. Style
使いたいスタイルを選択します。
ShareThis Step 2
Step 3. Customization
Drag & Drop で SNS ボタンの追加や並び替えを行います。
[Sharing Buttons] が ShareThis の用意した シェアボタンです。
[Other Social Plugins] は 「いいね!(Like)」 や Google+1 のようなボタンをそのまま使うタイプのものです。
ShareThis Step 3
Get the Code
ShareThis 自身のボタンのタイプを選択し、コードを取得します。
ShareThis 自身のボタンはいろいろな SNS にシェアできるポップアップを表示します。 表示されているカウンター値は他の SNS のシェアのカウントを合計したものです。
ShareThis Get the Code

ボタンはそのままでは現在のページが対象となってしまうので、 複数記事の場合には対象のタイトルや 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 開発の傾向を書いて、とやっているうちに変に広がった内容になってます。



スライド版はこちらです。





ここからブログ版です。

目次

  1. MVC 以前
  2. MVC - 拡張 MVC 時代
  3. MVVM(.NET)
  4. .NET 以外の傾向

MVC 以前

最初に MVC 以前の状態とともに UI アーキテクチャーにおける前提ついてお話します。

UI アーキテクチャーの大前提

MVC 以降いろいろな UI アーキテクチャーが登場しますが、 共通している目的は アプリケーションのコア部分と UI 部分を分離する ということです。

これはかっこよく言うと、次のようになります。
ビジネスロジックとプレゼンテーションロジックを分割する

MVC 以前ではそれらを 1 つのオブジェクトにまとめる傾向があったらしいです。
MVC 自体は賛否両論あるかも知れませんが、 そういった考えが広まり、 UI アーキテクチャーが注目されるきっかけとなったことは 大きな意味があると思います。



もう一つ最初に伝えておくべきことは 完璧な UI アーキテクチャーはない ということです。

銀の弾丸などない という格言があります。
ソフトウェア開発では、魔法のように問題を解決するような技術は存在しないことを示唆する言葉です。 これは UI アーキテクチャーでも同様です。

そのため、最後に出てきた UI アーキテクチャーでも決定版とはなりません。
問題がでてきて、新しいものが生まれるという繰り返しが今後も続いていくでしょう。

MVC と 拡張 MVC

MVC (GoF 本)

MVC が広くつかわれるようになったのは、 『 GoF 本』 で紹介されたことが大きかったでしょう。
そこで、『 GoF 本』 での MVC から始めることにします。
prog_mvc_gof.png
モジュール 説明
Model アプリケーションオブジェクト、データ管理
View 画面の表現
Controller ユーザー入力に対するインターフェース



もう少しわかりやすいように Wikipedia にあったシナリオをコラボレーション図風にしました。
prog_mvc_wikipedia.png



今までの説明で MVC は理解できたでしょうか ?

Model 、 View の方はわりとわかりやすいと思います。
しかし、 Controller はわかりづらいです。 ユーザー入力に対するインターフェースといわれても、 "View に入るんじゃないの ?" と思う人も多いでしょう。

また、ちゃんと理解できたとしても、"もっといい方法があるんじゃないか" と指摘したい点も多々あるんじゃないでしょうか。
例えば、 私は Model から View へ矢印がでているのは、結合が密になりよくないと思います。


誤解されたり、改良されたりで、 MVC は人によって解釈が様々になってしまっているのが現状です。
MVC が何を指しているのか、はっきり言って正解はわかりません。

今度は、この変化していった Web、 PC での MVC について見ていきます。

MVC (Web)

Web サービスで広く使われている MVC フレームワークとして Ruby on Rails があります。 これは次のようなアーキテクチャーです。
prog_mvc_rails.png
モジュール 説明
Model DB へのアクセス
View html ページと html ページの作成
Controller 入力の受け取り。他のモジュールの操作
Web の場合は View と Controller の違いははっきりしてます。
View は html ページとその作成を担当します。 CGI は アドレスとパラメーター(アドレスの ? の後など)を受け取り、処理を行います。 その受け取り部分が Controller です。



Model と View ではなく、なぜ MVC としたのでしょうか ?

『 GoF 本』 では Controller を分ける利点をいくつか挙げられています。
  • キーボードの応答を変えたり、メニューからの呼び出しに変更するとき、表示方法を変更しなくていい。
  • 入力イベントを無視するといったことをコントローラーのインスタンスの入れ替えで可能。
その他にも "View を入れ替えれば、 PC アプリ、 Web アプリでも使えるように" という理由もあります。
ちょっと無理そうな話ですが、例えば、 PC アプリが次のような構成であれば、 入れ替えて使うということができるかも知れません。
prog_mvc_pc_mvc.png
ただし、アプリが複雑化してくると、すぐ厳しくなってくるはずです。
やはり、これは欲張りすぎというものでしょう。

拡張 MVC (PC アプリ)

次に PC 上で動作するデスクトップアプリケーションの場合です。
この場合は、 Widget や Control といった GUI ツールキットが提供する部品を組み合わせて作成します。

高機能な部品になってくると、どうしても表示と入力処理を兼ね合わせるものになってしまいます。 このため、 View と Controller の分離は不可能になってきます。

『 GoF 本』 で指摘されている機能はほとんど GUI 部品の方で機能を持っていますし、 普通は PC 向けだけに作るので、あまり Controller を分ける必要もありません。


そこで、でてきたのが V と C をまとめて View とする拡張 MVC です。 (拡張といいつつ、減っていますが...)
これは、コアと UI 分離という基本原則だけ残った形です。
prog_mvc_ex.png
拡張 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 - プレゼンテーションモデル
  • アプリケーションモデル
これらのアーキテクチャーについては次のサイトで詳しく説明されています。 ただし、ここで MVC の拡大解釈が話を複雑にします。
例えば、 MVP の Presenter は簡単にいうと M と V の "つなぎ" の役割ですが、 Controller の名前でそのように使われることもあります。

また、 こういった UI アーキテクチャーは GUI ツールキットなどで、 フレームワークとして提供されないとなかなか定着しづらいものです。

要望

新たな要望も出てきます。
これはデザインの重要性が高まりからきています。

Web サイトは大手企業などでは Web デザイナーが作成しています。 それと同じように画面デザインもデザイナーに任せたいという要望です。

しかし、そのためには 画面レイアウトとコードを分離する必要が出てきます。
ただ、これは GUI ビルダーでも、昔から試行錯誤されているところなので、古くからの要求ともいえます。

画面レイアウト、コード分離の難点

GUI アプリケーションでは必然的にイベント駆動プログラミングとなります。
これが分離のネックです。

イベント駆動では呼び方はいろいろありますが、基本的に次のような仕組みです。
  • シグナル(イベント) → コールバック
prog_mvc_event.png
  • ループで画面を表示
  • イベント発生(ボタンクリックなど)
  • コールバック関数が呼ばれ、処理を実行
  • ループに戻る
このボタンなどの部品とコード上で定義されたコールバック関数を結び付ける必要があります。

MVVM(.NET)

問題点の解決のため、 .NET では MVVM が使わるようになってきました。

.NET の登場

  1. Win32API と MFC
  2. Java の台頭
  3. C#、.NET で対抗
1.
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 の方が使い方は想像しやすいです。
      また、使っている人が少ない → いいドキュメントも少ない ということもあります。
  • 長い間 MS 製品ですら使われなかった
    • 「さぁ、使ってください」と出された WPF ですが、 使う場合には「本当に実用に耐えうるの ? 」 というのは気になるところです。
      そんな中、 MS 自身が自分のところの開発に使っていないとなると「大丈夫かこれ。」と思うのは当然でしょう。

MVVM の登場

WPF はなかなか使われません。 しかし、だからといって Form のままでは問題点と要望が解決できません。
  • View の肥大化
  • 画面レイアウトとコードの分離
ここで問題解決のための MVVM の登場となります。
流れとしては MVP → PM → MVVM といった感じです。 と、その前に採用されている技術を紹介しましょう。
  • データバインディング
  • コマンドパターン

データバインディング

今更ですが、データを扱う部分は Data や Core ではなく、 何故 Model というのでしょうか ?

ここでの Model の意味はモデル化、モデリングといった時と同じで抽象化の意味です。
データは XML ファイルや DB などですが、これをプログラム内では扱いやすい構造体(オブジェクト)などに変換して使います。 データそのものではなく、構造体などに抽象化しているところなので、 Model です。
prog_mvc_databind.png

デスクトップアプリでは、 Model 内でデータを構造体(オブジェクト)として直接管理することもありますが、 多くはファイル、 DB から構造体(オブジェクト)に変換する必要があります。
この技術をデータバインディング といいます。
ただ、 プログラミング言語にメタプログラミング(リフレクション)の機能が必要だったり、 C++ のようにそれがない言語では特殊な前処理が必要だったりとそうそう簡単にできるものでもありません。

設定画面でよくあるパターン

『 GoF 本』にでてくるようなパターンではありませんが、 設定画面などでよく使われる手法があります。

それは画面の内容と構造体(オブジェクト)との相互に変換する機能を持たせることです。
デフォルト値があったり、部品の値がそのまま確定ではないモーダルなダイアログだったりする場合に向いています。
prog_mvc_vdatabind.png
通常、この変換は自分で実装しないといけないのですが、 WPF ではこの実装を助ける機能があり、双方向データバインディングと呼ばれています。


これ、 Model で使われるものと似ていないでしょうか ?
画面(View)を構造体(オブジェクト)に変換することで、抽象化しています。 ViewModel の由来は View 用の Model というところからきています。

双方向データバインディングにより、 ViewModel のオブジェクトの値を変更すると画面が変更され、逆に画面を変更すると ViewModel の値が変わります。 画面を抽象化した ViewModel としておくことで、プレゼンテーションロジックのテストがやりやすくなります

コマンドパターン

こちらは『 GoF 本』にもでてくるパターンです。

要求をオブジェクトでカプセル化するパターンで、 いろいろなところからの呼び出しに対応しやすくなります。
prog_mvc_command.png

MVVM

MVVM は次のような構成です。
prog_mvc_mvvm.png

画面レイアウトとコードの分離

View
XAML : XML でレイアウト定義
ViewModel
  • データ: 双方向バインディングで同期 (大部分をこれで行う)
  • コマンド : 必要最小限のイベント駆動
View で画面の作成を行い、このレイアウト定義を XML に記述します。
これにより、 画面デザインは Expression Blend などのデザインツールで行えるようになります。

パラメーター項目の設定などはデータバンディングを使い、 [OK] ボタンを押すといった必要最小限だけイベント駆動にします。
これにより、なるべくコードと分離しています。

View の分割

拡張 MVC (MV) における View の部分を ViewViewModel に分割することで肥大化を軽減しています。

ただ、 ViewModel がコマンドの管理だけならば、 Controller と区別しづらく、MVC に取り込まれていたかもしれません。
データバインドが MVVM の特徴です。

逆にデータバインドの機構がないと実装が大変なため、 MVVM は WPF 用の UI アーキテクチャー と言えます。

MVVM の実装

確かに MVVM は WPF 用の UI アーキテクチャーです。
しかし、注意していただきたいのは、 WPF は MVVM フレームワークではないということです。

これは次のようなことを意味します。
  • WPF で作れば MVVM になるわけではない
    • MVVM のアーキテクチャーを崩さないよう意識して実装する必要がある
  • MVVM を実装するには毎回同じようなコードを書く必要がある
毎回同じようなコードを書くのは面倒なことです。 そこで MVVM 用のライブラリー(フレームワーク)がいくつか存在します。
(『 MVVM 入門 その4「ライブラリを使おう」 言語: C# Visual Studio 2010 用』)

.NET 以外の傾向

.NET 以外にも、最近の傾向について触れておきます。

Web アプリケーション

問題のところで Web では JavaScript の部分が大規模化していると記述しました。
この解決策としては、 JavaScript の部分もフレームワークを使うというものがあります。
prog_mvc_js_mvc.png
よく使われるフレームワークは Backbone.jsAngularJS といったもので、 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 + JavaScript
JQuery MobileTitanium といったフレームワークがあります。

.NET 以外の PC アプリ

.NET 以外の PC アプリでも Mozilla の XUL、 Qt の QML のように 画面レイアウト定義に XML が使われる傾向があります。
.NET と違うのは、これらは HTML のように JavaScript を使います。 JavaScript をにかわ(glue)言語として使う構成です。
prog_mvc_js_pc.png
対象 作成
画面レイアウト XML
GUI 部品 GUI ツールキットが提供(C++)
アプリケーション全体 JavaScript
コア、スピードネック部分 C++
また、 GNOME でも GUI アプリは JavaScript を使うようになって来ています。

今後、どうなる ?

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 つの共通化が実現できる日がくるかも知れません。


 
このページをシェア
アクセスカウンター
アクセスランキング
[ジャンルランキング]
コンピュータ
31位
アクセスランキングを見る>>

[サブジャンルランキング]
プログラミング
5位
アクセスランキングを見る>>
カレンダー(アーカイブ)
プルダウン 降順 昇順 年別

08月 | 2023年09月 | 10月
- - - - - 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30


はてな新着記事
はてな人気記事
ブロとも申請フォーム
プロフィール

yohshiy

Author:yohshiy
職業プログラマー。
仕事は主に C++ ですが、軽い言語マニアなので、色々使っています。

はてブ:yohshiy のブックマーク
Twitter:@yohshiy

サイト紹介
プログラミング好きのブログです。プログラミング関連の話題や公開ソフトの開発記などを雑多に書いてます。ただ、たまに英語やネット系の話になることも。