japan.internet.comThe Internet & IT Network
Twitter
RSS
  • ニュース
  • コラム
  • リサーチ
  • ヘッドライン
  • 特集
  • ブログ
  • プレスリリース
  • 専門チャンネル
  • イベント
  • ランキング
  • ニュースメール
2009年11月21日
文字サイズ文字サイズ小文字サイズ中文字サイズ大
今年も各携帯キャリアが冬モデルを発表!買う予定はありますか?
今年中に買う予定
来年には買う予定
しばらく買う予定はない
現在の携帯が壊れるまで買わない
投票締切 11/23 12:00
デベロッパー2006年9月5日 11:00

Visual Studio 2005でのリモーティングに役立つ13のヒント

海外海外internet.com発の記事
  • Post to Twitter
  • Post to Facebook
  • このエントリーを含むはてなブックマーク
  • この記事をクリップ!
  • Buzzurlにブックマーク
  • Yahoo!ブックマークに登録
  • newsing it!
  • この記事をokyuuへインポート

はじめに

 本稿は「The Baker’s Dozen」シリーズの一記事です。本稿では、リモーティングとリモーティングインターフェイスの概要を解説します。

 .NETリモーティングを使用すると、マシンの物理的な境界の外側で実行されているコード(例えば、アプリケーションサーバー上のクラスにアクセスするWebサービスや、クライアント/サーバー環境の中間層にアクセスするクライアントアプリケーションなど)を呼び出して実行することができます。こうしたコードは、コードが置かれているドメインで実行されます。

 リモーティングは、別のドメインにあるコードを実行するための理想的なアプローチです。リモーティングインターフェイスを使うことで、現在のプロジェクトの外側にある厳密に型指定されたモデルのコードにアクセスするプログラムを作成することができます。リモーティングソリューションの構築には工夫が必要なので、初めはWebサービスより複雑な感じを受けるかもしれません。そこで、本稿では、簡単なリモーティングプロジェクトを少しずつ説明しながらリモーティングを分かりやすく紹介します。まず、リモーティングアーキテクチャの概要とリモーティングのさまざまな使い方を説明してから、リモーティングの基本的な性質を詳しく説明します。また、Visual Studio 2005におけるリモーティングの新しい機能もいくつか紹介します。最後に、高度なリモーティングを解説しているWebサイトを紹介します。

目的

 ここ数ヶ月間、私はVisual Studio 2005でのリモーティングに関する記事を書く予定でいたのですが、数週間前からリモーティングに直接関係するさまざまな質問をインターネットで目にしてきました。例えば、インターフェイスの実践的な使用に関する質問や、ジェネリックの価値に関する質問、リモーティングがWebサービスより好ましい理由についての質問などがありました。こうした質問はこの記事を書く刺激になりました。

 私は1年半に渡り、「Baker’s Dozen」シリーズで特定の技術や経験のある人を対象とした記事を書いてきました。今回紹介するヒントは次のとおりです。リモートアプリケーションの基礎知識と、インターフェイスの使い方を解説します。

  • リモーティングアーキテクチャの概要
  • リモーティングの実装オプション(TCPおよびHTTP)
  • リモーティングインターフェイスを定義する
  • リモーティングによってアクセスするビジネスオブジェクトを定義する
  • クライアントサイドを定義する
  • サーバー(リスナ)を定義する
  • Visual Studio 2005でデータセットリモーティングのパフォーマンスを向上させる
  • Windowsサービスを作成する
  • Visual Studio 2005におけるTCPリモーティングの新しいセキュリティ強化
  • Visual Studio 2005のジェネリックの概要
  • ジェネリックを使ってリモーティングインターフェイスを簡易化する
  • リモーティングオブジェクトファクトリを作成する
  • リモーティングオブジェクトファクトリを使用する

 Visual Studio 2005と特に明記されていない限り、これらのヒントの多くはVisual Studio 2003にも当てはまります。本稿の最後に、リモーティングに役立つ参考サイトを紹介します。では、始めましょう。

ヒント1:リモーティングアーキテクチャの概要

 初めに非常に簡単な例を紹介しましょう。中間層(外部メソッド)にある別のクラスを呼び出す必要があるローカルクラス(クライアントクラス)があるとします。外部メソッドは顧客キーに基づいて顧客データを取得します。クライアントクラスとリモートメソッドは別々のアプリケーション境界にあるので、クライアントクラスは、外部メソッドが取得するデータがプロジェクトファイルなのか参照なのか分かりません。クライアントクラスが外部メソッドを実行する場合、外部メソッド内のコードは外部メソッドが置かれているドメインで実行しなければなりません。

 最初は、リフレクションに使って外部メソッドを動的に検索して読み込もうと思うかもしれません。それも可能ですが、このアプローチを使うときは、モジュール、名前、場所などを指定できることが前提となります。

 この問題を解決するには、呼び出し側のプロジェクトと外部メソッドの両方が使用できる厳密に型指定されたリモーティングインターフェイスを定義します。TCPリモーティングを使って、アプリケーション境界を越えて外部メソッドにアクセスします。厳密な型指定によるアプローチは効率性に優れ、ランタイムエラーが発生することもほとんどありません。

 これを実行するステップをまとめると、次のようになります。

  1. GetCustomerメソッドの定義を入れる厳密に型指定されたインターフェイス(ICustomer)を作成します。
  2. 基本ビジネスオブジェクト(BaseBzObject)クラスを作成し、そこから外部メソッドを継承します。この基本ビジネスオブジェクトそのものはSystem.MarshalByRefObjectから継承します。これはリモーティングに必須のクラスです。
  3. 顧客ビジネスオブジェクト(CustomerBzObject)を作成します。このオブジェクトは、BaseBzObjectから継承し、ICustomerを実装して、GetCustomerメソッドを含める、という3つのことを行います。
  4. リスナを作成します。これはCustomerBzObjectを登録するリモーティングサーバーです。クライアントクラスはTCPポートを介して登録されているクラスにアクセスし、アクティブ化することができます。
  5. 簡単なクライアントを作成します。このクライアントは、リモーティングサーバー/リスナがモニタする同じTCPポートを介して、ICustomerインターフェイスへの型参照を使ってオブジェクトをアクティブ化します。

 以上5つのステップは、リモーティングで扱う「もの」を表します。リモーティングの「方法」と「理由」については、ヒント3〜7で説明します。

ヒント2:リモーティングの実装オプション

 リモーティングにはTCPとHTTPの2つの種類があります。これで、.NET Webサービスを追加するときの分散コンピューティングの選択肢は合計で3つになります。これらの実装は組み合わせることも可能で、例えば、クライアント層とアプリケーション層の間でWebサービスを使い、アプリケーション層の内側でリモーティングを使うことができます。

 3つの実装オプションを使う一般的な理由は次のとおりです。

  • ASP.NET Webサービスは、SOAP over HTTPをサポートしなければならない場合や、アプリケーションにアクセスするアプリケーションが.NET以外の場合に使います。
  • HTTPリモーティングは、すべての層に必ず.NETを使うけれどもHTTPも利用しなければならないインストールシステム向けのオプションです。IIS下でリモーティングコンポーネントをセットアップして認証機能とセキュリティ機能を使うことができます。
  • Visual Studio 2003のTCPリモーティングは、セキュリティを必要としない内部アプリケーションに最適のオプションでした。TCPリモーティングは通常は(厳密にはインスタンスによって異なりますが)3つの中で一番高速です。また、Visual Studio 2005では、セキュリティ機能を提供してTCPリモーティングを拡張しています(ヒント9を参照)。これにより、内部アプリケーション以外のアプリケーションにもTCPリモーティングを利用できるようになりました。

 Visual Studio 2005ではリモーティングがさらに強化され、アプリケーション境界を越えてバイナリ形式でデータセットをシリアライズできるようになりました(ヒント7を参照)。これにより、データセットとXML文字列の間の変換をプログラミングする必要がなくなり、物理的な境界を越えて渡すデータセットのサイズが縮小されます。

ヒント3:リモーティングインターフェイスを作成する

 ヒント1で説明したように、最初のステップはインターフェイスの作成です。アクセス先となる外部クラスがこのインターフェイスを実装します。クライアントはこのインターフェイスを使って外部クラスにアクセスします。

using System;
using System.Text;
using System.Data;
namespace SimpleInterfaces
{
   public interface ICustomer
   {
      DataSet GetCustomer(int AccountID);
      // we could have more, like a
      // SaveData method
      //void SaveData(DataSet CustomerData);
   }
}

 このインターフェイスのGetCustomerメソッドには実際のコードが何も書かれていないことに注意してください。ここで大切な点は、このインターフェイスを実装するすべてのクラスはGetCustomerというメソッドを持たなければならない、ということだけです。これは、アカウントID(AccountID)を受け取ってデータセット(DataSet)を返すメソッドです。詳しくは後で説明しますが、クライアントサイドに必要なのはこれだけです。

ヒント4:バックエンドリモーティングオブジェクトを作成する

 次のステップは外部ビジネスオブジェクトの作成です。簡単に言えば、外部クラスは次の3つのことを実行しなければなりません。

  1. ICustomerを実装します。
  2. MarshalByRefObjectという.NETのシステムクラスを継承します。これにより、リモートコードは外部メソッドのドメインにあるクラスを実行できるようになります。
  3. 基本ビジネスオブジェクトを継承します。

 ここで問題があります。1つのクラスは1つのクラスと1つのインターフェイスを継承することはできますが、複数のクラスを継承することはできません。この問題を解決するには、MarshalByRefObjectを継承する基本ビジネスオブジェクト(BaseBzObject)を定義します。これで、BaseBzObjectを継承してICustomerを実装する実際のビジネスオブジェクト(SimpleCustomerBzObject)を定義することができます。

 これにより、SimpleCustomerBzObjectBaseBzObjectを通してMarshalByRefObjectを継承するようになります。

 BaseBzObjectのコードは次のとおりです。

using System;
using System.Collections.Generic;
using System.Text;
namespace SimpleBaseBzObject
{
   public class BaseBzObject :
      System.MarshalByRefObject
   {
      // Base business object methods go here
   }
}

 SimpleCustomerBzObjectのコードは次のとおりです。

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using SimpleBaseBzObject;
using SimpleInterfaces;
namespace SimpleCustomerBzObject
{
   public class CustomerBzObject : BaseBzObject,
      ICustomer
   {
      public DataSet GetCustomer(int AccountID)
      {
         // do something, return a dataset
      }
   }
}

ヒント5:クライアントを作成する

 インターフェイスとサーバーサイドのビジネスオブジェクトを作成したので、次にこのバックエンドオブジェクトにアクセスするコードを作成する必要があります。

 既に説明したように、クライアントには顧客ビジネスオブジェクト(CustomerBzObject)もその参照もありません。あるのはインターフェイスだけです。お気づきの通り、必要なのはこのインターフェイス(とポート番号とアドレス)だけです。

 次のコードは外部クラスにアクセスする方法を示しています。

using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using SimpleInterfaces;
ICustomer oRemoteCustomer;
Type tCustomer = typeof(ICustomer);
ChannelServices.RegisterChannel( new TcpClientChannel());
oRemoteCustomer =
   (ICustomer)Activator.GetObject(tCustomer,
   "tcp://localhost:8228/CustomerBzObject");
DataSet DsTemp = oRemoteCustomer.GetCustomer(123);

 このコードが実行することは次のとおりです。

  • System.Runtime.Remoting名前空間への参照を追加します(コードには示されていません)。
  • 複数の.NETリモーティング名前空間と、インターフェイスクラスを組み込みます。
  • ICustomerインターフェイスへのオブジェクト参照を定義します。最終的にはこのオブジェクト参照を使って、バックエンドメソッドGetCustomerにアクセスします。
  • ICustomerへの型参照を定義します(サーバーサイドはオブジェクトの型と一致させるためにこれを必要とします)。
  • TCPチャネルを開きます(この例では、ポート8228とTCPアドレスをハードコーディングしています)。
  • リモートオブジェクトをアクティブ化し、戻り値をICustomerにキャストします。この時点で、oRemoteCustomerICustomerで定義されているすべてのプロパティとメソッドにアクセスできるようになります。

 最も重要なのは、リフレクションを使わずにこれらを実現できたということです。厳密な型指定によるソリューションを構築することができました。図1に、ICustomerが実装しているすべてのメソッドがデザイン時にIntelliSenseに表示されることを示します。自分だけでなく開発チームのメンバとも協力して、厳密に型指定された要素をできるだけ多く使うようにしましょう。デザイン時解決とタイプセーフチェックは、特にコラボレーション環境で有益な手法です。

図1 クライアントサイトのリモーティングは厳密に型指定されたインターフェイスを使う
図1 クライアントサイトのリモーティングは厳密に型指定されたインターフェイスを使う

ヒント6:リモーティングサーバーリスナを作成する

 もう1つ必要なパーツがあります。ビジネスオブジェクトに関するメソッドコードが置かれているドメインで、リスナを作成する必要があります。このリスナはクライアントコードで指定されたポートをチェックし、リモートアクセス用のビジネスオブジェクトを登録します。

using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
TcpServerChannel Tcps;
int nTCPPort = 8228;
Tcps = new TcpServerChannel(nTCPPort);
ChannelServices.RegisterChannel(Tcps);
RemotingConfiguration.RegisterWellKnownServiceType(
   typeof(SimpleCustomerBzObject.CustomerBzObject),
   "CustomerBzObject", WellKnownObjectMode.Singleton);

 このコードは少し難解に見えますが、メソッドの名前は一目瞭然です。ビジネスオブジェクトが置かれているドメインはTCPポートチャネルとCustomerBzObjectを登録します。クライアントサイドのコードを参照すると、オブジェクトの型参照がどのように一致しなければならないかが分かります。

ヒント7:Visual Studio 2005でデータセットリモーティングのパフォーマンスを向上させる

 一般的なデータドリブンアプリケーションでは、ある物理的な境界から別の境界へとデータセットを渡します。データセットはオーバーヘッドが大きいため、よく目にするのがデータセットとXML文字列の間で変換を行って転送のオーバーヘッドを削減する手法です。

 うれしいことに、Visual Studio 2005では、データセットをバイナリファイルとしてシリアライズすることでパフォーマンスを向上させることができます。

DsCustomer.RemotingFormat = SerializationFormat.Binary;

ヒント8:Windowsサービスを作成する

 ヒント7では、リモートコールを待機する基本的なWindowsフォームのアプリケーションのコードを示しました。実際、ほとんどのインストールシステムではリスナがWindowsサービスとして実行されています。

 Windowsサービスは、Visual Studio 2003とVisual Studio 2005のどちらでも作成できます。開発者の中には、このプロセスを「簡単すぎて怖いくらいだ」と表現する人もいます。サービスのエンティティ(プロセスインストーラなど)のセットアップについて知る必要はほとんどありませんが、幸い、.NETでWindowsサービスを作成する方法についてはインターネット上で情報がたくさん公開されています。

 本稿のサンプルファイルには、Windowsサービス用のプロジェクトが収録されています。

ヒント9:Visual Studio 2005におけるTCPリモーティングの新しいセキュリティ強化

 Visual Studio 2003では、IIS下にHTTPリモーティングオブジェクトを置いてセキュリティ手段を確保しなければなりませんでした。Visual Studio 2005では、TCPチャネルが強化され、セキュアなTCP通信を構成することができます。特に、TCPリモーティングは、SSPI(Security Support Provider Interface)を使って暗号化と認証をサポートしています。

 クライアントサイドで、必要なセキュリティ設定がすべて含まれた簡単なコレクションを定義し、そのコレクションをTCPチャネルのコンストラクタに渡すことができます。

Dictionary<string, string> oDict =
   new Dictionary<string, string>();
oDict.Add("secure", "true");
TcpChannel oChannel =
   new TcpChannel(oDict, null, null);
ChannelServices.RegisterChannel(oChannel);

 サーバーサイドでは、2つ目のパラメータ(ensureSecurity)をtrueに設定する必要があります。

Tcps = new TcpServerChannel(nTCPPort);
ChannelServices.RegisterChannel(Tcps,true);

ヒント10:ジェネリックの概要

 ジェネリックはVisual Studio 2005で最も話題になっている新しい言語機能の1つです。ジェネリックの説明でよく目にするのが、以前のバージョンの.NETではサポートされていなかったものであるということです。代表的な例がコレクションです。従来は、コレクションにあらゆる型のオブジェクトへの参照を格納しており、コレクション内の特定インデックスの値を取得するときにはキャストを実行していました。そのため、コンパイル時のタイプセーフが保証されず、キャスト時にボックス化とボックス化解除が生じるせいでパフォーマンスが低いという欠点がありました。

 新しいVisual Studio 2005の名前空間Systems.Generic.Collectionsを使えば、コレクション作成時に受け付けるメンバの型を指定することができます。これにより、コンパイラは事前に宣言されている型のオブジェクトの追加のみを認めるようになります。その結果、コレクションから値を取得するときにキャストを実行する必要はなくなりました。

 昨年秋にニュージャージー州で開かれたMSDN CodeCampで、Carl Franklinが行ったジェネリックの説明は、私がこれまでに聞いた中で最も短いものでした(www.DotNetRocks.comを参照)。Franklinによると、「ジェネリックは、内部型が異なる複数のクラスを簡易化する素晴らしい方法である」ということです。これを踏まえて、次のヒントに移ります。

ヒント11:本稿のスポットライト:ジェネリックを使ってリモーティングインターフェイスを簡易化する

 先ほどのごく簡単な例には、1つのインターフェイスと1つのメソッドしか含まれていませんでした。もっと現実的なアプリケーションを考えてみましょう。モジュールが12あり、それぞれのモジュールに基本キーのデータを取得するメソッド(GetProductGetAccountGetCostCenterなど)が含まれているとします。また、さまざまなモジュールに、別のカテゴリの関数があることも考えられます。このようなアプリケーションでは、ものすごい数のインターフェイスが必要になるのでしょうか?

 Visual Studio 2005では、必ずしもそうなるとは限りません。Carl Franklinの「ジェネリックは内部型が異なる複数のクラスを簡易化する」という考えを応用すれば、1つの基本キーの整数(例えば、アカウントキーまたは製品キー)を受け取ってデータセット(例えば、アカウント結果または製品結果)を返すジェネリックインターフェイスを定義することができます。

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
namespace GenericInterfaces
{
   public interface IRemoteGenericResultSet<T>
   {
      DataSet GetResults(int nID);
   }
}

 構文に注意してください。<T>というプレースホルダは、これがジェネリックであることを示しています。実際の型を参照するときには、同様にして実際の型を指定します。次のコードは、このジェネリックインターフェイスを実装するオブジェクトへの参照を示します。

string cServer = "tcp://localhost:8228";
object oRemoteObject = Activator.GetObject(
   typeof(IRemoteGenericResultSet<DataSet>), cServer + "/GetCustomers");
IRemoteGenericResultSet<DataSet> oCustomer =
   oRemoteObject as IRemoteGenericResultSet<DataSet>;
oCustomer.GetResults(111);

 呼び出し側のプロシージャには特定のモジュールへの型参照は含まれていません。バックエンドオブジェクトの名前に関するリテラルがあるので、そのリテラルを文字列またはプロパティに簡単に挿入できます。

 これは、ジェネリックを使ってプログラミングを簡易化する方法の一例です。ジェネリックの詳細は、「Baker’s Dozen」シリーズの今後の記事で取り上げる予定です。

ヒント12:リモーティングオブジェクトファクトリを作成する

 リモーティングを簡易化するもう1つの手段として、リモーティングの詳細を独立したクラスに分離する方法があります。リスト1に、リモーティングオブジェクトファクトリのコードを示します。アプリケーションから数多くのリモートオブジェクトにアクセスする場合は、このファクトリをインスタンス化し、ポート、サーバー、インターフェイス、および型参照に関するプロパティを目的のバックエンドオブジェクトのものに設定して、戻り値を適切なインターフェイスに渡します。

リスト1 クライアントサイドのリモーティングファクトリのコード
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime ;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
namespace SimpleClientRemotingFactory
{
   Public class RemotingFactory
   {
      private static int _nTCPPort;

      public int nTCPPort
      {
         get {return _nTCPPort  ;}
         set {_nTCPPort  = value;}
      }

      private static string _cTcpServer;
      public string cTcpServer
      {
         get {return _cTcpServer  ;}
         set {_cTcpServer  = value;}
      }

      private Type _tInterface;
      public Type tInterface
      {
         get {return _tInterface  ;}
         set {_tInterface  = value;}
      }

      private string _cRemoteObjectName;
      public string cRemoteObjectName
      {
         get { return _cRemoteObjectName; }
         set { _cRemoteObjectName = value; }
      }

      public RemotingFactory()
      {
      }

      public object GetRemoteInterfaceObject()
      {
         object oAccessObject = new object();
         IChannel[] myIChannelArray =
            ChannelServices.RegisteredChannels;
         if(myIChannelArray.Length ==0)
            ChannelServices.RegisterChannel(
            new TcpClientChannel());
         // activate back-end object
         oAccessObject = Activator.GetObject(
            this.tInterface, this.cTcpServer.ToString().Trim() +
            ":" + this.nTCPPort.ToString().Trim()  +
            "/" + this.cRemoteObjectName  ) ;
         return oAccessObject;
      }
   }
}

ヒント13:リモーティングオブジェクトファクトリを使う

 次に、ファクトリの簡単な使用例を示します。

using SimpleInterfaces;
RemotingFactory oFactory = new RemotingFactory();
oFactory.nTCPPort = 8228;
oFactory.cTcpServer = "tcp://localhost";
oFactory.cRemoteObjectName  = "CustomerBzObject";
oFactory.tInterface = typeof(ICustomer);
ICustomer oRemoteCustomer;
oRemoteCustomer = (ICustomer)oFactory.GetRemoteInterfaceObject();
DataSet DsTemp= oRemoteCustomer.GetCustomer(111);

 このコード例は、アドレスプロパティの設定方法を示しているだけで、実際のリモーティングコードは含まれていないことに注意してください。ここで重要なのは、リモーティングオブジェクトファクトリによってリモーティングの複雑さがすべて隠されていることです。

コメント

 ここ1年間で、リモーティングに対する開発者の反応についていろいろなことを知りました。開発者の多くは、リモーティングは複雑だと思って敬遠しています。そこで私は、少しの手間をかければ、リモーティングに必要な処理をアプリケーションの他の部分から分離できるということを実証しようと思い立ちました。最初にわかったことは、リモーティングは少し複雑だが少し勉強すれば慣れるということでした。今では、私は可能なときにはいつでもリモーティングを使っています。

 また、リモーティングを使っている開発者が多いという嬉しい驚きもありました。Indigoなどの新しいテクノロジーを待っている開発者もいますが、目下のアプリケーション問題を解決する方法を今すぐ知りたがっている開発者もたくさんいます。ちなみに、現在あるテクノロジの使い方を具体的に紹介することが、この「Baker’s Dozen」シリーズの目標の1つです。

まとめ

 リモーティングと、厳密な型指定による開発のメリットをお分かりいただけたでしょうか。今後、新しいMicrosoft開発テクノロジー(Indigo)が現れても、少なくとも当面の間はリモーティングが使われ続けるでしょう。

参考資料

 リモーティングについて勉強したことのある人ならば、Ingo Rammerという名前に聞き覚えがあるでしょう。Ingo Rammerは、リモーティングの分野でトップクラスの専門家の1人です。Ingo Rammerの教えを受けたい人は、www.thinktecture.com/を参照してください。

 リモーティングのソースコードの例は、MSDNオンラインのほかに、www.c-sharpcorner.comwww.codeproject.comでも公開されています。www.TheServerSide.netでは、有益な記事が数多く紹介されています。www.Developer.comや、Microsoftのパブリックニュースサーバーのニュースグループにも、有益な情報が数多く掲載されています。

著者紹介

Kevin S. Goff(Kevin S. Goff)
.NET、Visual FoxPro、SQL Server、Crystal Reportsによる独自のWebソリューション/デスクトップソリューションを提供するコンサルティンググループ「Common Ground Solutions」の創業者兼主任コンサルタント。ソフトウェアアプリケーションの開発経験は17年に及ぶ。米農務省からシステムオートメーション関連の賞をいくつか受賞。また、6桁の投資見返りを実現するソリューションを開発したことによりFortune 500企業から特別表彰を受ける。保険、会計、環境衛生、不動産、出版、広告、製造、金融、日用品、貿易振興など多様な業界に携わった経験を持ち、さまざまな形態で独自のトレーニングも行っている。
  • プリンター用
  • 記事を転送
  • Post to Twitter
  • Post to Facebook
  • このエントリーを含むはてなブックマーク
  • この記事をクリップ!
  • BuzzurlにブックマークBuzzurlにブックマーク
  • Yahoo!ブックマークに登録
  • newsing it!
  • この記事をokyuuへインポート
最新トップニュース
Graphic Design Forum
【Graphic Design Forum】
流動的媒体と静的媒体に関する見解(11月18日)
「IT の耳」
「IT の耳」
【書評】『Hyper-V スタートアップバイブル』――仮想化についてのすぐれた解説書(11月20日)
百式のネットビジネス研究
百式のネットビジネス研究
世界でもっともパワフルな iPod のスピーカー「Wall of Sound」(11月20日)
週刊-サイト別アクセス状況データ
週刊-サイト別アクセス状況データ
ビデオリサーチインタラクティブ調査(月間インターネットオーディエンスデータ)(11月19日)
海外ソーシャルウェブに学ぶ成功の秘訣
海外ソーシャルウェブに学ぶ成功の秘訣
ゲーム業界を襲う世界的な激震。ソーシャルゲーム急成長のインパクト(11月19日)
今さら聞けない初歩からのアクセス解析
今さら聞けない初歩からのアクセス解析
サイトリニューアル前のアクセス解析活用法(11月19日)
成約率、反応率を上げる Web 文章術
成約率、反応率を上げる Web 文章術
文章力を磨き、キャッシュを生み出す Web サイト に(11月19日)
「Webからの脅威」―その傾向と最新対策
「Webからの脅威」―その傾向と最新対策
新たな対策技術:スパムフィルタリングと E-mail レピュテーション(11月18日)
ROI向上のための戦略的WebPR
ROI向上のための戦略的WebPR
「戦略的 WebPR」のしかけ方〜WebPR の効果測定手法とは〜(11月18日)
スマートにソーシャルウェブを構築しよう
スマートにソーシャルウェブを構築しよう
社員力を生かすソーシャルメディアポリシー(11月17日)
DevX
DevX
Erlangを使った並列処理プログラムの作成(11月17日)
Copyright 2009 Japan Internet.com K.K. All Rights Reserved.http://www.internet.com/