<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Rのメモ帳 &#187; Spiderの実装</title>
	<atom:link href="http://brandish.xrea.jp/wordpress/?feed=rss2&#038;tag=spider%E3%81%AE%E5%AE%9F%E8%A3%85" rel="self" type="application/rss+xml" />
	<link>http://brandish.xrea.jp/wordpress</link>
	<description>Regihsが送るぐだぐだな日々の中で思いついたことを書き綴るページです。</description>
	<lastBuildDate>Wed, 25 Jul 2012 01:19:38 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Spiderの実装 (2)</title>
		<link>http://brandish.xrea.jp/wordpress/?p=177</link>
		<comments>http://brandish.xrea.jp/wordpress/?p=177#comments</comments>
		<pubDate>Fri, 10 Jun 2011 00:11:31 +0000</pubDate>
		<dc:creator>regihs</dc:creator>
				<category><![CDATA[Spider]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Spiderの実装]]></category>

		<guid isPermaLink="false">http://brandish.xrea.jp/wordpress/?p=177</guid>
		<description><![CDATA[Spiderを実装するうえで頭を悩ませたのは、細かな違いを吸収し、統一された方法でデータベースにアクセスするためのDatabaseインターフェイスです。 インターフェイスのメソッドを実行するたびにSQLをコンパイルしてい &#8230; <a href="http://brandish.xrea.jp/wordpress/?p=177">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Spiderを実装するうえで頭を悩ませたのは、細かな違いを吸収し、統一された方法でデータベースにアクセスするためのDatabaseインターフェイスです。</p>
<p>インターフェイスのメソッドを実行するたびにSQLをコンパイルしていたのでは動作が重くなって仕方ありませんので、Connection#prepareStatement()でプリコンパイルしておかなければなりません。このタイミングとして、(1) Databaseの実装オブジェクトを構築するときにプリコンパイルする、(2) 各メソッドを実行するときにプリコンパイルする、という方法が考えられます。効率の面を考えれば、(2)ではメソッドを実行するたびにPreparedStatementのフィールドが初期化されているかを調べなければならないので、(1)の方が優れています。(1)は初期化に時間を要しますが、すべてのメソッドが使われるのならば、総計では変わりありません。nullチェックが入る分、(2)の方が（若干ですが）重くなります。</p>
<p>ただ、効率よりも考えるべきなのは、コードの見やすさです。(1)はコンストラクタ、または初期化メソッドにすべてのSQLを書き込まなければならず、そのSQLを使う部分とは離れてしまうことになります。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> Database1 <span style="color: #000000; font-weight: bold;">implements</span> Database
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> Database1 <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">prepared</span> <span style="color: #339933;">=</span> connection.<span style="color: #006633;">prepareStatement</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT ...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// 初期化するSQLが増えていけば、ここがどんどん伸びていく</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">int</span> getData <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">long</span> id<span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">prepared</span>.<span style="color: #006633;">setLong</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, id<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #003399;">ResultSet</span> rs <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">prepared</span>.<span style="color: #006633;">executeQuery</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// ...</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>もっとも、エディタの上下分割機能を使えば解決するという問題でもあります。しかし、個人的には、そのような機能を使わずとも、SQLと、そのSQLを利用するコードは近くに配置したいという気持ちです。</p>
<p>一方、(2)の方法を採るのならば、SQLと、そのSQLを利用するコードは近くに配置することができるようになります。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> Database2 <span style="color: #000000; font-weight: bold;">implements</span> Database
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> PreparedQuery prepared<span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">int</span> getData <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">long</span> id<span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">prepared</span> <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">prepared</span> <span style="color: #339933;">=</span> connection.<span style="color: #006633;">prepareQuery</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT ...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">prepared</span>.<span style="color: #006633;">setLong</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, id<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #003399;">ResultSet</span> rs <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">prepared</span>.<span style="color: #006633;">executeQuery</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// ...</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>SQLが遠く離れていると、何番目のパラメータに何のデータを入れればよいのか分かりにくくなってしまいますが、このようなコーディング方法であれば必ず近くに配置されるので分かりやすさが向上します。しかし、この方法では、メソッドが実際に呼ばれるまでSQLがコンパイルされません。そのため、SQLに文法エラーがあるとき、発見が遅れることになります（先にコンパイルしておけばオブジェクト構築時にエラーが検出される）。もっとも、すべてのメソッドについてテストするようにしておけば、これは問題になりません。開発スタイルとしても、ちゃんとテストは行うべきです。次に、毎回nullチェックが入るため、動作速度が（きわめてわずかですが）遅くなります。フィールドは最初に初期化された以降nullになることがないので、このチェックは最初の一回以外すべて意味を持ちません。個人的には、このような無駄が気になって仕方ありません。</p>
<p>以上から、(1)のように、あらかじめSQLをプリコンパイルするようにしつつ、(2)のように、SQLと、そのSQLを使うコードを付近に配置するという方針を考えることにします。</p>
]]></content:encoded>
			<wfw:commentRss>http://brandish.xrea.jp/wordpress/?feed=rss2&#038;p=177</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spiderの実装 (1)</title>
		<link>http://brandish.xrea.jp/wordpress/?p=170</link>
		<comments>http://brandish.xrea.jp/wordpress/?p=170#comments</comments>
		<pubDate>Wed, 01 Jun 2011 12:24:29 +0000</pubDate>
		<dc:creator>regihs</dc:creator>
				<category><![CDATA[Spider]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Spiderの実装]]></category>

		<guid isPermaLink="false">http://brandish.xrea.jp/wordpress/?p=170</guid>
		<description><![CDATA[インターフェイスだけ定義してもプログラムは動作しませんので、実装をしなければなりません。 Spiderシステムは情報を蓄積して扱いやすいインターフェイスを提供するためのものですから、情報を蓄積するストレージが必要になりま &#8230; <a href="http://brandish.xrea.jp/wordpress/?p=170">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>インターフェイスだけ定義してもプログラムは動作しませんので、実装をしなければなりません。</p>
<p>Spiderシステムは情報を蓄積して扱いやすいインターフェイスを提供するためのものですから、情報を蓄積するストレージが必要になります。フリースタイル（自前でディスクへの保存などの機能を実装する）でもいいのですが、効率の良いものを構築する自信はありません。また、かなりの手間がかかるので、完成がいつになるのか分かりません。そこで、リレーショナルデータベースをストレージシステムとして利用することにします。幸いなことに、JavaにはJDBCという仕組みが用意されているので、データベースの操作は比較的に楽です。また、著名なデータベースのJDBCドライバも公開されています。</p>
<p>どのデータベースを利用するか悩むところですが、まだシステムが成熟しておらず、テスト段階であることを考えれば、手軽に使うことのできるものが望ましいといえます。とはいえ、いつまでも簡易なデータベースに頼っているようでは、システムやデータの規模が大きくなってきたときに対応できなくなるおそれがあります。そのため、特定のデータベースに依存しない設計を目指すことにし、最初は扱いやすいデータベース（SQLiteなど）で開発し、徐々に本格的なデータベース（MySQLなど）へ移行していくことにします。具体的には、NetworkやConceptはデータベースを抽象化したオブジェクトを介してデータベースと情報をやり取りします。そして、そのデータベースごとに仲介オブジェクトの実体を実装していきます。</p>
<p>簡略的に記述すれば、次のようになります。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">jp.blacksoft.spider_jdbc</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> Database
<span style="color: #009900;">&#123;</span>
    <span style="color: #008000; font-style: italic; font-weight: bold;">/**
     * @param id
     *            調べるオブジェクトの概念ID
     * @return オブジェクトの作成日時, オブジェクトが存在しなければ{@code null}
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Date</span> getConceptCreateDate <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">long</span> id<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">// etc...</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> JdbcNetwork <span style="color: #000000; font-weight: bold;">implements</span> Network
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">final</span> Database objDatabase<span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">// etc...</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000000; font-weight: bold;">class</span> JdbcConcept <span style="color: #000000; font-weight: bold;">implements</span> Concept
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
    @Override
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Date</span> getCreateDate <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">getDatabase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getConceptCreateDate</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">numConceptID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>各データベース用の実装クラスでは、Databaseで定義されたインターフェイスに合わせた情報を返すように、各データベースに応じたSQLを記述します。</p>
]]></content:encoded>
			<wfw:commentRss>http://brandish.xrea.jp/wordpress/?feed=rss2&#038;p=170</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
