<?xml version='1.0' encoding='Shift_JIS' ?>
<doc xml:lang='ja'>
	<head>
		<title>実装フェーズ</title>
	</head>
	
	<body>
		<p>実装フェーズの方法は、「モデル作成のプロセス」のものとほぼ同じです。
			今回は新しく次のような実装に挑戦します。
		</p>
		
		<ul>
			<li>Priorityの設定</li>
			<li>Typeの継承</li>
			<li>行動の継承</li>
			<li>WorldInitializerを使って初期化できる世界の実装</li>
		</ul>
		
		<subsection title="Typeを実装する">
			<p>RelationTypeとGoodsTypeの実装は前章の実装フェーズを同じように行いますが、
				Priorityの設定とTypeの継承が新しい項目です。
			</p>
				
			<program title="AgentTypeによるPriorityの実装(ArtificialMarketModel.java)"
				javasrcKeyword="initializePlugin"
				src="src/model/ArtificialMarketModel.java" normalizer="javasrc"
				javasrcSyntaxHilight="true" encoding="Shift_JIS" />
				
			<subsubsection title="Prirorityの設定">
				<p>
					BESPでは、AgentTypeごとにステップ毎のTimeEventの受け取り順を制御することが出来ます。				
					Priorityが高いAgentTypeのエージェントは、
					Priorityが低いAgentTypeのエージェントよりも先にTimeEventを受け取ることが保証されます。
				</p>
				<p>Priorityの設定はAgentTypeのインストール時に行います。
					ここでは、証券取引所のPriorityを通常のエージェントのPriorityよりも高く設定したいため、
					"ModelContainer.PRIORITY_DEFAULT + PRIORITY_StockExchange"に設定しています。
					（この場合PRIORITY_StockExchangeの値は1以上ならいくつでもよいでしょう。
					ただし、今後Priorityの間に他のPriorityを設定する場合を考えて、間をいくらか空けておくのが慣習となっています。）
				</p>
			</subsubsection>
			
			<subsubsection title="Typeの継承">			
				<p>
					BESPで規定されているすべてのTypeは「親子」関連をもつことが出来ます。（つまり継承ができるということになります。）
					多重継承もできますが、ループするような親子関係を持つことはできないようになっています。
				</p>
				<p>
					株式市場の例では、"TraderBehavior"の買い注文を決定するアルゴリズムが異なる行動
					"TrendTraderBehavior"と"RandomTraderBehavior"を用意しているので、
					投資家エージェントはこの異なる二つのアルゴリズムのどちらかを持つことになります。
					ただし、ここで問題があります。証券取引所が注文受付の情報を送る時に、
					"どちらの"行動に送ってよいのか分からないことです。
					この問題は、どちらのアルゴリズムもTraderBehaviorとして扱い（つまり継承を使い）、
					証券取引所は、TraderBehaviorに対して注文受付の情報を送ることで解決することが出来ます。
				</p>		
				<p>
					このようにすることで、投資家は、注文受付の情報が"TraderBehavior"宛てに送られてきたときに、
					"どちらかの"TraderBehaviorが自動的に選択され、受信することが出来ます。
				</p>		
				<p>
					このようなTypeの継承を使うためには、Typeクラスの.addChild(Type[子クラス])メソッドを利用します。
					親クラスに子クラスを追加した時点で、継承関係が成立します。
				</p>														
			</subsubsection>				

		</subsection>
		
		<subsection title="情報を実装する">
			<p>前章では、簡単な情報の実装を見ましたが、
				ここでは、少し複雑な情報を見ていくことにしましょう。</p>
			
			<p>株式市場で特に重要なのがOrderInformation(注文情報)、BoardInformation(板情報)です。</p>

			<program title="情報の実装(OrderInformation.java)"
				src="src/model/information/OrderInformation.java"
				normalizer="javasrc" javasrcSyntaxHilight="true"
				encoding="Shift_JIS" />
				
			<p>
				フィールド（属性）が増え、それに従いアクセサりメソッドも増えています。
			</p>
			<p>
				ここで、オーバーライドすると便利なtoString()メソッドについて説明します。
				OrderInformationは、そのときの注文の状態を表示するようにtoString()をオーバーライドしています。
				このようにしてオーバーライドされたtoString()メソッドは、log出力時に自動的に利用されます。
			</p>
			<p>
				つまり、オブジェクトの内部変数の状態を出力するようにtoString()メソッドをオーバライドすると、
				モデルが正しく動いているかのデバッグをする際に役に立つのです。
			</p>	
				
			<program title="情報の実装(BoardInformation.java)"
				src="src/model/information/BoardInformation.java"
				normalizer="javasrc" javasrcSyntaxHilight="true"
				encoding="Shift_JIS" />			
					
			<p>
				さて、この情報クラスは注文の管理から始まり、約定などの操作アルゴリズムも記述された、
				かなり、大規模なクラスです。
				これぐらいの大規模なクラスになると、コードを書くのはかなり厄介です。
			</p>
			
			<p>
				このようなクラスの設計･実装は、プログラミングに詳しい人の力を借りるのが一番なのですが、
				どうしても自分で作らなければならない場合、一つだけアドバイスをしておくことがあるとすれば、
			</p>
			<ul>
				<li>きちんと単体テストをする</li>
			</ul>
			<p>
				ことです。BESP上で動かす前に、各メソッドが正しく動くかどうか、簡単なmainメソッドを作って試してみましょう。
				最初からBESP上で動かしてしまうと、動作しない場合に、その情報クラスが正しく動作していない場合と、
				他の要因（状態遷移が正しくない、財の送受信がうまくいっていないなど）で動かないことと区別できなくなってしまいます。
			</p>
			<p>
				これぐらいの規模になったら、少し面倒でも確実に単体テストをするほうが、結局最終的にかかる時間は少なくて済む場合が多いです。
			</p>
		
			<p>		
				また、再利用可能な情報コンポーネントが増えれば、このようなクラスを書く可能性は減ってくるでしょう。
			</p>
						
			<!--
			<p>もう一度おさらいする意味で、人工市場モデルのPriceHistoryInformationを実装していきましょう。</p>
			<p>はじめに、InformationをimplementsしたPriceHistoryInformationクラスを作成します。</p>
			<p>次に、設計モデルクラス図を参照して、PriceHistoryは何を内部変数として持つべきかを確認します。
				この場合は、価格履歴を保持するList型の変数ひとつだけです。</p>
			<p>それから、このクラスの可変性について考えます。
				PriceHistoryInformationの場合、毎期、価格を追加したいのでaddメソッド、また履歴を参照したいのでgetterメソッドを記述します。</p>
			<p>そして、コンストラクタを実装します。</p>			
			<program title="情報の実装(PriceHistoryInformation.java)"
				src="src/model/information/PriceHistoryInformation.java"
				normalizer="javasrc" javasrcSyntaxHilight="true"
				encoding="Shift_JIS" />
			
			<program title="OrderInformation.javaのtoString()メソッド"
				javasrcKeyword="toString"
				src="src/model/information/OrderInformation.java"
				normalizer="javasrc" javasrcSyntaxHilight="true"
				encoding="Shift_JIS" />				
			-->
			
		</subsection>
		
		<subsection title="行動を実装する">
			
			<p>
				人工市場モデルに必要な行動は"StockExhangeBehavior"と"TraderBehavior"です。
				ここでは、"TraderBehavior"に的を絞り、継承を使ったプログラミングについて解説します。
			</p>
			
			<p>
				まず、親クラスである"TraderBehavior"を見てみましょう。
			</p>
			
			<program title="親クラス(TraderBehavior.java)"
				src="src/model/behavior/TraderBehavior.java"
				normalizer="javasrc" javasrcSyntaxHilight="true"
				encoding="Shift_JIS" />
							
			<p>
				取引の部分は共通部分ですので、親クラスに記述します。
				子クラスに委譲するのは、「注文を考える」アルゴリズムの部分ですので、ここをホットスポットにし、
				抽象メソッドcreateOrder()を用意しています。
			</p>
			
			<p>
				この抽象メソッドを実装したサブクラス２つを以下に示します。
				RandomTraderBehaviorの注文アルゴリズムは完全にランダムな（いわゆるノイズトレーダー）注文を行うのに対して、
				TrendTraderBehaviorは過去の価格履歴を参照してしながら注文を行うように実装しています。
			</p>
				
			<program title="ランダムに注文を行う行動(RandomTraderBehavior.java)"
				src="src/model/behavior/RandomTraderBehavior.java"
				normalizer="javasrc" javasrcSyntaxHilight="true"
				encoding="Shift_JIS" />
				
			<program title="過去の価格履歴を参照して注文を行う行動(TrendTraderBehavior.java)"
				src="src/model/behavior/TrendTraderBehavior.java"
				normalizer="javasrc" javasrcSyntaxHilight="true"
				encoding="Shift_JIS" />

		</subsection>
		
		<subsection title="世界を実装する(ArtificialMarketWorld.javaの実装)">
			<p>
				前章でBESPでは世界クラスによって初期状態を設定する基本的な方法を説明しました。
			</p>
				
			<p>
				ここでは、世界クラスを利用して、エージェントの人数などの「パラメータチューニング」を
				BESPを起動してから動的に変更できるようにするための実装方法を紹介します。
			</p>
			
			<subsubsection title="WorldInitializerでパラメータチューニングが出来る世界クラス">
				<p>
					初期パラメータ（初期エージェントの数など）の変更が動的に出来ない前章のレモン市場のような世界クラスでは、
					パラメータを変更するたびにプログラムを書き換え、コンパイルし、BESPを再起動する必要がありました。
					これは非常に不便です。
				</p>
				<p>
					このような不便を解決するために、BESPにはWorldInitializerという初期化機能がついています。					
					WorldInitializerを使うと、パラメータチューニングが動的に出来るようになり、非常に便利です。
				</p>
				<p>
					ただ、WorldInitializerを使うためには、WorldInitializerに対応した世界クラスを作る必要があります。
					しかしそれは、そんなに難しいことではありません。
					簡単に言えば、パラメータにsetterとgetterを適切な名前でつけるだけです。
				</p>
				<p>
					適切な名前とは、JavaBeansの仕様に従った名前ということです。
					例えば、変数名は小文字で始める、メソッド名はget変数名、 set変数名という名前を付けるという規則です。
					以下にJavaBeansの仕様に従った、変数の記述をまとめます。
				</p>
				
				<table style="width:100%" title="WorldInitializerで変更可能な変数の記述方法">
					<thead>
						<tr>
							<th>要素</th>
							<th>アクセス修飾子</th>
							<th>命名規則</th>
							<th>具体例</th>
						</tr>
					</thead>
					<tbody>					
						<tr>
							<td>変数</td>							
							<td>private</td>
							<td>任意(小文字で始める)</td>							
							<td>private int agentNum</td>
						</tr>
						<tr>
							<td>getter</td>							
							<td>public</td>
							<td>get[変数名]</td>							
							<td>public int getAgentNum()</td>
						</tr>
						<tr>
							<td>setter</td>							
							<td>public</td>
							<td>set[変数名]</td>							
							<td>public void setAgentNum(int agentNum)</td>
						</tr>	
					</tbody>
				</table>
				
				<p>変数、メソッドはstaticにしないよう注意してください。以下に人工市場の例を示します。</p>
					
				<program title="世界の実装(ArtificialMarketWorld.java)"
					src="src/model/ArtificialMarketWorld.java"
					normalizer="javasrc" javasrcSyntaxHilight="true"
					encoding="Shift_JIS" />
					
			</subsubsection>
			
		</subsection>
		
	</body>
</doc>
