goo blog サービス終了のお知らせ 

ウィリアムのいたずらの、まちあるき、たべあるき

ウィリアムのいたずらが、街歩き、食べ物、音楽等の個人的見解を主に書くブログです(たま~にコンピューター関係も)

サポートのメイド化、リモートサービスのいもうと化ですかね、次は。。。。

2006-09-01 18:52:40 | Weblog

 妹からのモーニングコールをバーチャル体験できる画期的なサービスができたそうな
ここのニュース

「おにいちゃん、おはよう!」妹からのモーニングコール
http://excite.co.jp/News/bit/00091156742573.html

によると(上記斜体は、上記のニュースより引用)。。。

これが、画期的なのは、この声、録音してあるんじゃなくって、人力なのだ(@_@!)
つまり、声優さんが、モーニングコールするのだ。。。

ちなみに、そのサイトなんだけど、URLがすごいぞ!
http://www.oni-tan.com/index.html
おにーたん、どっと混む。なのだ。。




 なるほどおおお、人力っていうのは、考え付きませんでしたねー。

 そのうち、ロボット受付も人力化したりして。。
 見た目はロボット受付なんだけど、実はそこのカメラ画像と音声は、沖縄のコールセンターに送られていて、そのコールセンターから答えている声が、あたかもロボットからの声のようにきこえるとか。。

 さらに、もともと人力化しているものに、萌えプラスっていうのもありますよね。。
 サポートを有料制にする代わりに、メイド風にサポート、メイドさんに嫌われたら、そこでサポート終了=>クレーマーをつぶせるなんていう感じ。。逆にメイドさんに好かれると、各種イベントご招待とか。。なんじゃそりゃ・・・

 あ、そうそう、いもうとデスクトップ、これ、人力にしちゃったら、ただのリモートサポートだよねえ。。つまり、リモートでサポートしてるんだけど、返事が、いもうと調と。。
 当然、自然言語で指示してOKです。
 おー、そーすると、今日はいもうと調、今日はツンデレと、いろいろかわるのかもしれません。

 なんかそのうち、電子秘書(もちろん人力)萌えバージョンとか、わかんないこと言い出しそう(パソコンを立ち上げると、メイド服を着た秘書が、答えて、秘書に指示すると、秘書が操作したり、メールを読み上げる)なんで、この辺で。。。

P.S。。。それって、たんに、秘書にメイド服を着せて、テレビ電話で話せば、いいだけじゃ。。(^^;) 



  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

Javaで基本操作(その8):分類(分類のためのレコード表現方法)

2006-09-01 16:38:53 | Weblog

 Javaで基本操作シリーズその8、今回は、分類、仕分けなのですが、これは、

1.ここに、ファイルの中身があります
2.ある基準をもとに
   A
   B
  の2つ(あるいは、2つ以上)に分けます

というものです。
 で、このプログラム自体はかんたんなのですが、問題は、ファイルの中身
 をどのように表現するかです。
Stringの配列やVectorにするのと、HashMap(あるいはHashTable)の2とおりあります。
HashMapだと、いろんな点で便利なことがあります。

 まず、Stringの配列やVectorにするほうで、具体的な例とコーディングをあげてしまいます。




■具体例の仕様

 以前あげた、タブ区切りファイルを読み込んで、価格(5番目の項目)が、40000以上と、それ未満にわけなさい。
 そして、40000未満を、コード(1番目)、名前(3番目)、金額(5番目)の順に表示しなさい




■サンプルプログラム(1レコードをString[](cell[])で表現)
import java.util.*;

public class test {
	/*
	 * 	メイン処理(呼び出し元)
	 */
	public static void main(String[] args) {
		int i,j;
		
		//==========================//
		//タブ区切りファイルの読込み//
		//==========================//
		Vector rec	=	Csv.read("test.txt");
		if ( rec	==	null )
			return;

		//==========================//
		//	分類		//
		//==========================//
		Vector hi40000	= new Vector();	//40000より高い
		Vector low40000 = new Vector();	//40000より安い
		
		for(i = 0 ; i < rec.size() ; i ++ )
		{
			//	レコード取得
			String[] cell = (String[])rec.elementAt(i);

			//	比較データ取得
			int val;
			try
			{
				val = Integer.parseInt(cell[4]);	
			}
			catch(Exception e)
			{
				continue;
			}

			//	比較して分類
			if ( val >=	40000)
			{
				hi40000.add(cell);
			}
			else
			{
				low40000.add(cell);
			}
		}
		
		//==========================//
		// 分類したものの表示	//
		//==========================//
		for(i = 0 ; i < low40000.size();i++)
		{
			String[] cell = (String[])low40000.elementAt(i);
			System.out.println(cell[0]+"¥t" + cell[2]
                                    +"¥t" + cell[4]);
		}
	}

}

(上記< > ¥は、本当は半角です)

 タブ区切りファイルの読み込みCsv.read("test.txt");に関しては、以前あげた、タブ区切りファイルのところにあります。
 入力ファイルは、そこのファイルのうち、5番目の要素の価格について、カンマを取ったものです(そうしないと、エラーになってしまう)

 ここで、Vectorの各要素が1レコードになっていて、その中身はString[]です。




■1レコードを配列で表現する場合、ハッシュマップにする場合
 上記のように1レコードを配列で表現しても、仕様変更がない場合は、そんなに問題ありません。でも、仕様が変更した場合とかを考えると、位置で指定する配列は、項目が増えたり減ったりすると、そのたびに書き換えとなりめんどうです。

 そこで、1レコード分をハッシュマップにいれ、
  キーを項目名
  値を実際のデータ
 そうすると、変更が少なくなります。なお、HashMapでなく、Hashtableでやることもありますが、理屈は同じです。




■サンプルプログラム(1レコードをHashMapで表現)
仕様は、初めのものと同じです。で、

「レコードを入れる:ここ追加」

のところでハッシュマップにいれております。
import java.util.*;

public class test {
	/*
	 * 	メイン処理(呼び出し元)
	 */
	public static void main(String[] args) {
		int i,j;

		//==========================//
		//タブ区切りファイルの読込み//
		//==========================//
		Vector rec	=	Csv.read("test.txt");
		if ( rec	==	null )
			return;

		//==========================//
		//レコードを入れる:ここ追加//
		//==========================//
		Vector tmprec = new Vector();
		for(i = 0 ; i < rec.size() ; i ++ )
		{
			//	レコード取得
			String[] cell = (String[])rec.elementAt(i);

			HashMap mp = new HashMap();
			mp.put("コード",cell[0]);
			mp.put("市場",cell[1]);
			mp.put("名前",cell[2]);
			mp.put("時間",cell[3]);
			mp.put("金額",cell[4].replaceAll(",",""));

			tmprec.add(mp);
		}
		rec	=	tmprec;
		//==========================//
		//	分類		//
		//==========================//
		Vector hi40000	= new Vector();	//40000より高い
		Vector low40000 = new Vector();	//40000より安い

		for(i = 0 ; i < rec.size() ; i ++ )
		{
			//	レコード取得
			HashMap mp = (HashMap)rec.elementAt(i);

			//	比較データ取得
			int val;
			try
			{
				val=Integer.parseInt((String)mp.get("金額"));
			}
			catch(Exception e)
			{
				continue;
			}

			//	比較して分類
			if ( val >=	40000)
			{
				hi40000.add(mp);
			}
			else
			{
				low40000.add(mp);
			}
		}
		
		//==========================//
		// 分類したものの表示	//
		//==========================//
		for(i = 0 ; i < low40000.size();i++)
		{
			HashMap mp = (HashMap)low40000.elementAt(i);
			System.out.println(mp.get("コード")+"¥t" +
                                mp.get("名前")+"¥t" + mp.get("金額"));
		}
	}

}

(上記< > ¥は、本当は半角です)
ファイルでなく、DBからのデータの場合、このように入っているので、
むしろ、こちらのほうが、両方同じ形式にできて、扱いやすいと思います。


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

デザインパターンの23種類の各パターンは、要するにこうだ!と言い切る(その2:構造関連編)

2006-09-01 11:35:00 | JavaとWeb

 以前に書いた、デザインパターンの話のつづき、今回は、構造に関するものです。

 GoF本では、デザインパターンを主に3つに分けている。
 1つめは、生成に関するもの
 2つめは、構造に関するもの
 3つめは、振る舞いに関するもの

1つめの生成はわかりやすいです。3つめの振る舞いというのも、これはメソッドに関するもんだと思いをめぐらすことができます。。。が、構造っていわれても。。。クラス割り?
 いまいちはっきりしませんが、そうやって割っているので、そういうことにしましょう。




 で、今回は、構造に関するものです。ここに属するものは

・Adapter   いわゆるラッパー
・Bride    機能と実装をわける
・Composite  違うものを1つの上位クラスにいれて、同じように扱う
・Decorator  付け足す
・Facade    入り口を1つにする
・Flyweight  オブジェクトの共有
・Proxy    代わりに処理する

って感じです。
今回も、どーいうことがいいたいのかを中心に書いていきます。
(順番は変えます。簡単なもんから説明していってます)




■Facade
 入り口を1つにする。これは、どっかのサーバーを呼び出すなんていうケースで、サーバー側のプログラム(呼び出し)は、今後増えていくなんていうようなケースのとき、とりあえず、

int execute(HashMap argMap);

というすべて、同じインターフェースにして、argMapの
キー"command" の値に呼び出すメソッドを設定、
それ以外のキーと、値に、その呼び出すメソッドで必要な引数を記述してもらって、
全部入り口はこのメソッドで共通にする

などというときに使います。





■Adapter
 いわゆるラッパーです。
 2つのメソッドが違うとき、たとえば、上記の例だと

 int execute(HashMap argMap);

 というメソッドが入り口で、呼び出すメソッドは int doJob(String arg1,String arg2);
 などと、違ったものかもしれません。このとき
 2つの違ったメソッドを呼び出し可能にするラッパーがAdapterです。





■Proxy
 代わりに処理する。
 たとえば、上記のサーバーを呼び出す場合、1回呼び出してしまったら、検索の場合、帰ってくる値は、2度目も3度目も同じでいいというケースがあります。(データベースのコードテーブルなどである)。
 こういうとき、
クライアント側にも
 execute(HashMap argMap);
というメソッドを用意し、このメソッドをみんな使ってもらい、
 このメソッド内では、
・新規のアクセスの場合は、サーバーアクセスして
 execute(HashMap argMap);
 を呼び出し、その結果を返すと同時に、どこかにプールしておく
・2度目以降のアクセスの場合、プールした内容の中にあれば、
 サーバーにアクセスしないで、プールした値を返す。

などというとき、クライアントのexecuteメソッドは、サーバーのexecuteメソッドのproxyであるといいます(HTTPのプロキシも、キャッシュを使って似たようなことしてる)





■Flyweight
 オブジェクトの共有。singletonのとき、1個のオブジェクトしか作らないで共有しましたが、あれとおなじです。ただし、1個だけじゃなくって、複数個作って共有することもあります。





■Bride
 機能のクラスと実装のクラスをわけます。
 なにがいいの、とか、どうやるの。。っていうのは、

 Java言語で学ぶデザインパターン入門
 第9章(121ページから)を見てください。かならずしもメリットだけとは限りません(と思います。クラスが深くなりやすい)。





■Composite
 違うものを1つの上位クラスにいれて、同じように扱う。
 いろんな種類のあるものを(再帰とかするため)、まとめて扱いたいとき、上位クラスをつくって、そいつから、それぞれの種類のクラスをextendしてやるものです。

 具体的に、違うものとしてファイルとディレクトリで、それを同じものとみなして再帰させるというプログラムが

 Java言語で学ぶデザインパターン入門

第11章(153ページから)にあります。





■Decorator
 付け足すとき、なんですけど、機能を追加する場合、包むことによって機能を追加する方法です。

 ファイルの読み込み(FileReaderクラス)のとき、バッファを使って行うようにしようとした場合、BufferedFileReaderというクラスを、FileReaderから継承してつくって、

 BufferedFileReader in = new BufferedFileReader(foo.in);

 ってしても、いいんだけど、もしそうすると、今度はソケットを使いたい場合、BufferedSocketReaderっていうクラスを作って、

 BufferedSocketReader in = new BufferedSocketReader("www.yahoo.co.jp",80);

ってやんないといけなくなってしまいます。
 さらに、BufferdFileReaderを機能追加した、ExtraBufferdFileReaderっていうのを考えたら、それのソケット対応のために、ExtraBufferedSocketReaderっていうのもつくって。。。

 入出力増えたらたいへんそう(>_<!)
 つまり、機能を継承で追加すると。。。。大変なことになる場合があります。

 java.ioでは、そういうことはしてなくて、FileReaderを、BufferedReaderがつつむことで、バッファリングした読み込み機能を追加する、つまり

BufferedReader in
= new BufferedReader(new FileReader("foo.in"));

とします。ソケットの場合
Socket socket = new Socket("www.yahoo.co.jp",80);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

ってします。このとき、BufferedReaderは、ファイル用、ソケット用とは、別れません。
これは、継承でなく、委譲という方法を使って実現しているのですが、これが、Decoratorのパターンです。

具体的に、これをどうやって実現するのかとか、継承と委譲の説明その他もろもろは
 Java言語で学ぶデザインパターン入門

第12章(169ページから)にあります。




 だんだん面倒になってきて、後のほうはみんな

  。。。を見てください

 になってしまった(^^;)


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする