SlideShare ist ein Scribd-Unternehmen logo
1 von 177
1
2
3
◆クラスとインスタンス
オブジェクト指向はオブジェクトを基本に考えていきますが、このオブジェクトの設計書がクラスです。
クラスという設計書から実際のオブジェクトを作り出すわけですが、この作り出されたオブジェクトが
「実体化されたモノ」であることを特に明確に表す言葉としてインスタンスという言葉も使われます。た
だし、「オブジェクト」と「インスタンス」は、それほど大きな違いがあるわけではなく、ほとんど同じ意味
で使われます。
◆継承と汎化
人間は物事を整理するときに、同じ特質を持つものを同じ種類として分類します。さらにその種類の
上位に、より大きな単位で同じ特質を持つグループを作ったりします。たとえば人間という動物を「霊
長目ヒト科」として分類して理解するのがこれにあたります。こうしておけば、情報を整理し、体系的に
理解することができます。たとえば霊長目の特質を知れば、「人間」の特質を知ることができると同時
に、霊長目に属する他の動物(ニホンザルなど)についての特質も知ることができます。
これをソフトウェアの設計や実装で実現するのが継承と汎化という概念です。したがって、継承や汎
化を適切に使うことで、多くの情報を整理してわかりやすくすることができます。
◆カプセル化
オブジェクト指向では、個々のオブジェクトを独立した存在として考えます。オブジェクトが独立して存
在するためには、オブジェクトの内と外を明確に分け、中身が外からむやみに触れられないようにす
る必要があります。たとえば、携帯電話が1つのオブジェクトである場合、中にある基板を勝手にいじ
ると、携帯電話というオブジェクトの動作が保証されなくなります。そこで、オブジェクトの中身を外か
ら簡単には操作できないようにする必要かあります。このようにオブジェクトの中身を隠すことをカプ
セル化と言います。
◆インターフェース
カプセル化を行った場合でも、そのオブジェクトには外からアクセスできるようにする必要があります。
このオブジェクトへのアクセス方法を定義しているのがインターフェースです。インターフェースでは、
どのような名前で呼び川し、どのような情報を入力すれば、どのような情報が返ってくるかを定義しま
す。


                                                    4
インターフェースが明確になっていれば、オブジェクトの中で何が行われているかをまっ
たく知らなくても、そのオブジェクトを外側から利用することができます。
◆具象クラスと抽象クラス
クラス内には、そのオブジェクトが外部からインターフェースを通じて呼び出されたときに
行う処理を記述しておく必要があります。具体的な処理を含み、実際にインスタンス化
できるクラスのことを具象クラスと言います。それに対して、インターフェースの定義だけ
で具体的な処理をまったく(あるいは一部しか)含まず、直接的にはインスタンス化でき
ないクラスのことを抽象クラスと言います。
◆多態性/多様性
これらはオブジェクト指向の中でも特にわかりにくい概念です。しかし、これも継承や汎
化と同様に、物事を表現するための情報を整理し、効率的にやり取りすることを可能に
する考え方です。
あるオブジェクトが他のオブジェクトを呼び出す場合のことを考えてみましょう。呼び出し
側オブジェクトには解決したい問題があり、それを処理してもらうために他のオブジェクト
を呼び出します。このとき、呼び出し側オブジェクトの目的は「問題を解決すること」で
あって、「オブジェクトを呼び出すこと」ではありません。つまり、問題を解決できさえすれ
ば、相手側がどのオブジェクトであろうとも関係ないのです。これを利用して、呼び出し
側オブジェクトにはある問題を解決するために使うインターフェースだけを知らせておき、
実際にその処理を行うときには、相手側がどのオブジェクトなのかに関係なく、決まった
インターフェースを呼び出すようにすることができます。こうすると、呼び出し側が知って
いなければいけない情報を減らしつつ、複雑な処理を実現できるようになります。この
考え方と仕組みが多態性・多様性です。
◆集約と委譲
オブジェクト指向では、オブジェクトは互いに独立して存在すると考えますが、オブジェク
トの中でも関係性の深いオブジェクト群があったり、あるオブジェクトが他のオブジェクト
に依存していたりすることもあります。こうしたオブジェクトの依存関係を示すのに使わ
れるのが集約です。
この概念は、再利用を考えたときに重要になってきます。非オブジェクト指向のプログラ
ミングでは、ライブラリという形で処理を何度も再利用できるようにしていました。オブ
ジェクト指向では、処理とデータを含む「オブジェクト」を単位として再利用を行う場合が
あります。この再利用では、オブジェクトどうしは集約の関係になり、実行したい機能を
持つオブジェクトに処理を任せることになります(これを委譲と言います)。この方法を適
切に使うとオブジェクト指向の効果を最大限に発揮できます。
◆メッセージ送信
オブジェクトは互いに独立していて、複数のオブジェクトが協調して動作します。このとき、
あるオブジェクトが他のオブジェクトにメッセージを送信することで要求を出します。この
メッセージのやり取りによって一連の処理や動作を遂行します。
◆UML
オブジェクト指向で分析・設計を行い、設計書を記述する場合には、オブジェクト指向の
考え方を視覚的に示すための表現手段が必要です。また、その表現手段は、自分だけ
でなく他の人も読むことができるように統一化されていなければなりません。こうした要
求を満たすオブジェクト指向設計のための表記法がUML(Unified Modeling Language:統
一モデリング言語)です。オブジェクト指向の設計を表現する際にはUMLが使われるの
が一般的で、UMLはオブジェクト指向開発者の必須知識と言えます。




                                                         4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
(1) 基本フローに記述するのは、正常ケースの中の一つの流れのみ
基本フローには、正常終了する一つの流れのみを記述します。その流れ通りにはならない場合は、
すべて代替フローに記述します。
(2) 代替フローには、実行される条件を明示する
代替フローの一行目「2a 条件に一致する書籍が一つもない場合」という記述を見てください。最初の
数字「2」は、基本フローの2行目で起こり得るフローということを、「a」は識別子を意味します。“条件
に一致する書籍が一つもない場合”という部分は、代替フローが実行される条件です。
(3)概念モデルに対して何をするのかという観点で記述する
基本フローのシステムが実施する内容を見てください。2行目と4行目がそれです。それぞれに“書
籍”という記述があります。これは、概念モデル上で出てきた“書籍”と同一のものです。概念モデル
はシステムの静的な構造を、ユースケースはシステムの動的な構造を表しますから、ユースケース
上に書くシステムが実施すべき内容というのは、概念モデル上の概念を操作することに相当するわ
けです。
(4) ユーザー・インタフェースの操作は記述しない
ユースケース記述の中には、前述のようにユーザー・インタフェースに関する記述は一切入れません。
ユーザー・インタフェースの設計は、別途、画面仕様書なり画面遷移図なりを作成しそちらで行いま
す。
(5) 各フローの中にすべてを記述しようとしない
フローの中にすべてを記述しようとしても無理があるので、備考をうまく利用してなるべくわかりやすく
書きます。上記の例では検索条件の詳細を備考に記述したり、ログのフォーマットは別ドキュメントを
参照するように記述しています。すべてをユースケース記述の中に記述する必要はないのです。




                                                    25
26
27
28
29
1.概念候補の導出
システム化の対象となる領域にどのような情報があるのかを抽出する作業
とにかく思いついたものをどんどん出すのがコツ
例えば、目に見えるもの(顧客、店、商品)、目には見えないが業務上管理しているもの(口座、在庫)、
業務上の重要なイベント(注文、売上、貸し出し)といった指針に基づいて抽出するとよい
2.概念候補のグループ化
導出した概念候補の中で結びつきの強いものを集めてグループ化する作業
ここで実施するグループ化は、概念モデリングを円滑に進めることを目的としたものなので、グルー
プ化の基準をあまり気にする必要はない
どのグループにも入らない概念候補がある場合は、“その他”のようなグループを作る
3.概念の特定
ここから先の作業は、各グループ別に行う
洗い出した各概念に対して以下のような観点でチェックし、概念として適当ではないものを除外して
いく
●同じ言葉でも、二つ以上の異なる意味があれば分割を検討する
●違う言葉でも、同じ意味のものがあればどちらかにまとめることを検討する
●何らかの概念の属性となるべきものをふるい落とす
●概念として適切な名前に変更する(例:「会計伝票」→「会計取引」。伝票そのものが重要なのでは
なく、伝票の中の情報が重要だから)
4.主属性の定義
各概念が何を表すのかをわかりやすくするために、主属性を定義する
そのときの指針として、
●各概念ごとに定義する属性は三~五つぐらいまで
●属性をすべて洗い出すことが目的ではない
●属性ではなく別概念となる場合もある
●(現段階では)データモデリングはしていないので、すべての概念に主キーを定義する必要はない


                                                   30
5.関連の定義
これまでの作業が完了した各概念間の“関連(Association)”を定義する
関係(Relationship)を持つ概念の間に、関連を示す線を引き、多重度を定義する




                                              30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
アーキテクチャパターン
アーキテクチャパターンは、「システム全体のアーキテクチャを決定する」段階で適用されま
す。アーキテクチャ(architecture)には「構造」という意味があり、ソフトウェア開発で「アーキテ
クチャ」と言えば、抽象度の高い構造的なまとまりのことを指します。代表的な例としては
MVC(Model-View-Controler)アーキテクチャが挙げられます。
MVCアーキテクチャは、データ管理を担当するコンポーネント(Model)、Modelへの変更を担
当するコンポーネント(Controller)、そしてユーザー向けの情報表現を担当するコンポーネント
(View)から成ります。各コンポーネントはそれぞれの仕事を専門的に担当します。
MVCアーキテクチャにはいくつかのバリエーションが存在し、VからMの矢印がない場合もあ
ります。MVCは、システム内の責任分担を明確にして、システムの機能拡張を容易にする
アーキテクチャパターンです。

アナリシスバターン
アナリシスパターンは「分析」の段階で適用されます。この段階では「ビジネスを人がどのように捉え
ているのか」を分析します。したがって、コンピュータのシステムに依存しないモデルを作成します。ア
ナリシスパターンの一例として「パーティパターン」があります。ここで言う「パーティ」とは社交的な集
まりのことではなく、「一行・グループ」の意味です。
ビジネスの世界では、人と組織には似通った性質があります。たとえば人も組織も電話番号を持って
いて、銀行の口座を持ったり、税金を申告したりすることもできます。そのため人と組織の類似部分
を「パーティ」としてひとまとめに考えることができます。アナリシスパターンの1つとして、このような分
析法をパーティパターンと呼んでいます。

デザインバターン
デザインパターンは「設計」の段階で適用されます。デザインパターンはアーキテクチャパターンやア
ナリシスパターンよりも粒度が小さく、イディオムよりも粒度が大きいということを覚えておいてくださ


                                                       58
い。

イディオム
イディオムは「コーディング」の段階で通用され、「プログラミングパターン」とも呼ばれま
す。
イディオムとは、特定のプログラミング言語に特化したパターンであり、具体的なソース
コードとして提示されることがよくあります。




                                             58
59
楕円はパターンを、楕円の大きさはパターンの粒度を表しています。
上図を見てもわかるとおり、パターンの粒度はアーキテクチャパターンからイディオムに向けて小さく
なっていきます。楕円を結んでいる矢印とその方向は、パターンの使用関係を表しています。矢印の
方向は上から下に向かっており、これはアーキテクチャパターンがアナリシスパターンを使用し、アナ
リシスパターンがデザインパターンを使用するということを表しています。つまり上から下に向けて
「使用する・される」関係にあることがわかります。一般的には、粒度の粗いパターンが粒度の細かい
パターンを内包し、使用することが可能です。




                                                 60
◆生成
・アブストラクトファクトリ(AbstractFactory)
関連するオブジェクトの生成方法をグループ化し、具体的なオブジェクトを特定せずに生成するため
のインターフェースを提供する。
・ビルダー(Builder)
オブジェクトの生成処理を担当するクラスを作成し、さまざまな生成処理を行えるようにする。
・ファクトリメソッド(FactoryMethod)
インターフェースを利用することで、直接具象クラスを明示してオブジェクト生成を行う必要をなくす。
・プロトタイプ(Prototype)
サンプルをコピーして生成したオブジェクトをクライアントに提供する。
・シングルトン(Singleton)
システム内に存在するオブジェクトが1つであることを保証する。
◆構造
・アダプター(Adapter)
インターフェースの変換を行うことによって、互換性のないクラスを利用できるようにする。
・ブリッジ(Bridge)
抽象的なインターフェースを2つに分割し、それぞれを自由に変更できるようにする。
・コンポジット(Composite)
集団を表現するオブジェクトと要素を表現するオブジエクトを同じように扱えるようにする。
・デコレータ(Decorator)
オブジェクトに動的に機能を追加するための構造を提供する。サブクラス化による機能追加より柔軟
な方法である。
・ファサード(Facade)
サブシステムへの統合されたインターフェースを提供することによって、サブシステムの利用方法を
簡素化する。
・フライウェイト(Flyweight)


                                                  61
細粒度のオブジェクトを共有することで、オブジェクトの格納コストを減少させる。共有さ
れるオブジェクトは使用状況に依存してはならない。
・プロキシー(Proxy)
WebサーバーやDBサーバーなど|こアクセスするプログラムを開発するときの便宜を図
る。
◆振る舞い
・チェーンオブレスポンシビリティ(Chain of Responsibility)
クライアントからの要求を処理できるオブジェクトをチェーンでつなぎ、そのチェーン中の
任意のオブジェクトが要求を処理するようにする。
・コマンド(Command)
クライアントからの要求をオブジェクトを用いてカプセル化する。何かを行うタイミングは
わかるが、具体的な処理内容がわからないときに使用する。
・インタープリタ(Interpreter)
言語の文法をオブジェクトで表現し、そのオブジェクトを用いてその言語の文を解釈する。
・イテレータ(Iterator)
集約オブジェクト内の個々のオブジェクトにアクセスするための統一化された手段を提
供する。
・メディエータ(Mediator)
オブジェクト間の複雑な協調関係を集中管理するオブジェクトを定義する。これによりオ
ブジェクトどうしの結合度を弱め、柔軟性を保つことができる。
・メメント(Memento)
カプセル化を侵害しない方法でオブジェクトの内部状態を保存し、後でその状態に戻れ
るようにする。
・オブザーバー(Observer)
あるオブジェクトが状態を変えたときに、そのオブジェクトに依存するオブジェクトに自動
的に状態変更が通知され、その依存オブジェクトが更新されるまでの仕組みを提供する。
・ステート(State)
各状態における振る舞いを記述した状態オブジェクトを導入する。状態によって変化す
る振る舞いをクラス内に記述する必要がなくなり、状態オブジェクトに処理を任せること
ができるようになる。
・ストラテジー(Strategy)
アルゴリズムの集合を定義して実装を力プセル化しておき、クライアント側に影響を与え
ずにアルゴリズムを変更・交換できるようにする。
・テンプレートメソッド(TemplateMethod)
スーパークラスのメソッドで手順を決めておき、順番に呼び出されているメソッドについ
ては、実装をサブクラスに任せることにする。
・ビジター(Visitor)
クラスの要素を変更せすに、新しい操作を定義できるようにする。




                                            61
62
通常、オブジェクトを生成するときはnewを使ってコンストラクタを呼び出します。コンストラクタ
を呼び出した回数だけ、初期化されたオブジェクトが生成されます。オブジェクトはシステムの
中のあらゆる箇所からあらゆるタイミングで利用される可能性がありますが、そのたびに初
期化されてしまっては都合が悪い場合もあります。このような場合には、システムの起動中
はオブジェクトを1つだけに制限したいという要件が出てきます。しかし、利用する側で生成す
るオブジェクトの数を管理するのは非常に困難です。そうした場合に役に立つのがシングルト
ンパターンです。シングルトンを適用すると、いつでもどこでも必ず同じオブジェクトを利用す
ることができます。
例としてプリンタのスプーラーを考えてみましょう。次の前提条件があるとします。
・プリンタは1台でコンピュータとは1つのポートで接続されている。
・同時には2つ以上のドキュメントの印刷はできない(当然ですが)。
・複数のオブジェクトの各々から印刷要求が発行される。




                                                 63
プリンタは1つしかないことです。したがって、プリンタのスプールを管理するPrintSpoolオブジェクトは、
常にシステム内に1つだけ存在しなければなりません。




                                                         64
main関数では、システム起動時にPrintSpoolオブジェクトを1つ生成します。この唯一のPrintSpoolオ
ブジェクトを複数のオブジェクトが共有して利用できるようにするには、Processオブジェクトの作成時
にPrintSpoolオブジェクトをパラメータとして渡します。




                                                             65
Processクラスでは、印字要求するprintOut()メソッドを定義します。このメソッドは印字したい文字列を
受け取り、スプールに出力します。実際のプリンタへの印字要求はスプールが行うことになります。
このままでもスプール処理は問題なく動作します。しかし、プリンタは1台であるという前提条件のた
め、スプールは通常1つであり、PrintSpoolオブジェクトも1つでなければなりません。
ところが現状の実装では、コードのどこかで次の記述を行えば、簡単に別のPrintSpoolオブジェクトを
生成できてしまいます。
PrintSpool* obj = new PrintSpool();




                                                           66
シングルトンパターンでは、「オブジェクトを1つだけ生成する」というロジックをそのクラス自身に持た
せます。今回の例では、PrintSpoolクラス内にオブジェクト生成の制限ロジックを含めることになります。
まず、外部のクラスがPrintSpoolクラスのオブジェクトをnewで生成できないようにします。
そのためには、次のようにしてコンストラクタをprivateにします。
しかし、このままでは代入によるコピーも可能となるため、コピーコンストラクタと代入演算子もあわせ
てprivateにする必要があります。




                                                        67
さらに、呼び出し側のクラス(関数)に唯一のPrintSpoolオブジェクトを提供するためのgetInstance ( )ク
ラスメソッドを準備します。このクラスメソッドは、instanceというstatic変数に保持しているPrintSpoolオ
ブジェクトのポインタを返します。instanceは、初めてgetlnstance ( )が呼び出されたときに、PrintSpool
のインスタンスを持つため、不変で唯一のオブジェクトが保証されます。
クラス内にこのような仕組みを用意しておくと、呼び出し側クラスがオブジェクトの有無を管理する必
要がなくなり、PrintSpool::getlnstance()という呼び出し方で、いつでもどこからでも唯一のオブジェクト
を取得できます。
ここまでが、シングルトンの基本となります。ポイントは次の2点です。
・コンストラクタをプライベートにし、外部からアクセスできないようにする
・getInstance( )クラスメソッドを用意し、プライベートクラス変数に保持している唯一のオブジェクトを返
すようにする




                                                                    68
69
パターン適用後のPrintSpoolクラスには、シングルトンのロジックを実現するgetlnstance()メソッドが用
意されています。Processクラスは、コンストラクタの引数としてPrintSpoolオブジェクトを受け取るので
はなく、printOut()メソッドの中でPrintSpoolクラスのgetlnstance ( )メソッドを呼び出すことで、唯一の
PrintSpoolオブジェクトを取得します。その結果、main関数内で, PrintSpoolオブジェクトを生成して
Processに渡す必要がなくなっています。




                                                                     70
マルチスレッドのアプリケーションで本パターンを使用する場合は注意が必要。
万が一、同時に複数のスレッドからgetInstance() が呼ばれた場合に予期しない動作となる可
能性があります。その場合は排他制御を行ってgetInstance()に対する同時アクセスを回避す
る必要があります。




                                                    71
ファクトリメソッドパターンでは、インターフェースを介することで、オブジェクトの生成を柔軟に行える
ようにします。
通常、オブジェクトを生成するときには、その具象クラスのコンストラクタを呼び出します。
OutputStream pStrearn1 = new BufferedOutputStream();
OutputStream pStream2 = new BufferedOutputStream();
この方法では具象クラスの名前を明示的に記述するので、同じクラスのオブジェクトを複数生成した
いときには、そのクラスの名前がコードの複数箇所に出てくることになります。
このような単純な方法には、コードの拡張や保守という点で問題があります。具象クラスを明示して
オブジェクトを生成していると、使用するクラスを切り普えたいときや、新たにクラスを追加するときに、
具象クラス名が出てくる箇所をすべて修正しなければならなくなり、柔軟性に欠けてしまいます。
ファクトリメソッドパターンでは、インターフェースを介してオブジェクトの生成を行うことで、生成される
側と生成する側の結びつき(結合度)を弱め、クラスの切り替えや新規クラスの追加を柔軟に行えるよ
うにします。
ソフトウェア開発の現場では、初めはダミークラスなどを使って開発を進め、後で実際のクラスに切り
替えたいという要求が発生する場合があります。このような場合にファクトリメソッドパターンを使うと
柔軟に対応することができます。
例として、製品IDから製品名称を取得する場合を考えてみましょう。次の前提条件があるものとしま
す。
・開発の最終段階では、データベースに登録されている製品情報から製品名称、を検索する
・データベースの設計やセッティングが完了していないので、現時点ではデータベースを利用できな
い。そのため、一時的にファイルを簡易データベースとして使用しながら開発を進めておきたい
・後でファイル利用からデータベース利用へと簡単に修正できるようにしたい




                                                       72
データベースが完成するまでは、ファイルからデータを取得するクラス(FileDataObject)を代わ
りに使うことにします。




                                                      73
このクラスを呼び出すクライアント(main関数)では、単純にnewを使ってFileDataObjectクラスのオブ
ジェクトを生成し、そのオブジェクトを使用します。




                                                            74
データベースが完成し、データベースを利用するクラス(仮にDBDataObjectとします)が使用で
きるようになれば、FileDataObjectオブジェクトの生成処理をDBDataObjectオブジエクトの生成
処理に書き換えます。
これをクラス図で示すと図のようになります。この図には、将来切り替える予定の
DBDataObjectクラスも入れておきます。FileDataObjectとDBDataObjectは同じ機能を持ってい
ますが、現在は2つの間に関連性はありません。




                                                                75
DataObjectクラスは、次のことを実現するためのクラスです。
・クライアント側が直接FileDataObjectの存在を知らなくても良いようにする
・FileDataObjectという具象クラスを明示したオブジェクト生成処理を1箇所だけに記述する




                                                    76
このDataObjectクラスのポイントは次のとおりです。
・クラスメソッドcreate() の中だけでFileDataObjectの生成処理を行っている
・create( )を呼び出した側 (main関数)は、このメソッドによって生成されたオブジェクトをDataObject型
として受け取るので、それがFileDataObjectであるかどうかを意識する必要がない
・getName()は純粋仮想関数として定義されており、実際の処理を含んでいないので、main関数が
getName()を呼び出したときには、DataObjectを継承したFileDataObjectクラス内のgetName()が実行
される

将来的にFileDataObjectクラスを置きかえるDBDataObjectクラスも、同じようにDataObjectクラスを継
承するようにします。
FileDataObjectクラスとDBDataObjectクラスの両方が同じDataObjectクラスを継承するところが、この
パターンの要です。
main関数側では、新たにオブジェクトを生成するときに、パターン未適用時のようにFileDataObjectク
ラスを直接インスタンス化するのではなく、DataObjectのクラスメソッドcreate( )を呼び出します。その
後は、create()メソッドから返されたオブジェクトを使用します。




                                                                     77
ファクトリメソッドパターンの目的は、クライアントへの影響を最小限に抑えつつ、クラスの切り替えを
容易に行えるようにすることです。そこで、前述の例で実際にクライアントへの影響が抑えられている
かどうかを確認してみましょう。パターン適用前とパターン適用後でクライアントコードがどのように変
化しているかを見比べてください。違うのはオブジェクトを生成している箇所だけです。
・パターン未適用:
FileDataObject* pDataObject = new FileDataObject();
・パターン適用後:
DataObject* pDataObject = DataObject::create();

パターン適用前とパターン適用後の違いをまとめると、次のようになります。
◆パターン未適用時
・newを使用してオブジェクトを取得する
・ファイルを利用するクラス(FileDataObject)の名前をクライアント側で明示的に指定する必要がある
◆パターン適用時
・メソッドの呼び出しでオブジェクトを取得する
・クライアント側では、ファイルを利用するクラス(FileDataObject)なのか、データベースを利用するクラ
ス(DBDataObject)なのかを意識する必要がない




                                                           78
ファクトリメソッドパターンを適用した場合にクラスの切り替えがどのくらい容易になるかを具体的に考
えてみましょう。
パターン適用前のサンプルとパターン適用後のサンプルで、ファイル利用クラス(FileDataObject)を
データベース利用クラス(DBDataObject)に切り替えてみます。
◆パターン未適用時
クライアントコードでnewを使ってFileDataObjectオブジェクトを生成している箇所を修正します。複数
の箇所で、FileDataObjectオブジェクトを生成している場合には、そのすべての箇所を探して修正する
必要があります。
◆パターン適用時
クライアントコードを修正する必要はありません。複数の箇所でFileDataObjectオブジェクトを生成して
いる場合でも、ファクトリメソッド(DataObjectクラスのcreate()メソッド)内でオブジェクト生成処理を行っ
ている1箇所を修正するだけです。




                                                              79
前記のファクトリメソッドは、引数がなく、決められたオブジェクトを返すだけでした。このままではクラ
イアントの要求に応じて適切なオブジェクトを生成することができません。そこで、どのオブジェクトを
生成するかという情報をクライアントから引数として渡すことにします。
DataObjectクラスでたとえば定数を追加します。
const static int STANDALONE = 0; //追加
const static int NETWORKING = 1; //追加
DataObject::create()を引数(int type)をとるように変更し、
if (type ==STANDALONE) result = new FileDataObject();
if (type == NETWORKING) result = new DBDataObject();
とするとします。

この例では、STANDALONEとNETWORKINGという定数を使用して、ネットワークに接続していない場合
と接続している場合を区別しています。
create()メソッドがSTANDALONEを受け取ったときはFileDataObjectオブジェクトを作成し、NETWORKING
を受け取ったときはDBDataObjectオブジェクトを作成します。
これでうまくいくように見えますが、実はこの方法では、クライアントがDataObjectをいくつも生成する
場合にはnewをしているのと変わらなくなってしまいます。

ここではオブジェクト生成の責任をcreate()という「メソッド」だけで果たそうとしていますが、メソッドで
は対応しきれないので、より大きな責任を負うことのできる「クラス」でオブジェクト生成を行うようにし
ます。このクラスの名前をDataObjectFactoryとします。




                                                                      80
DataObjectFactoryクラスでは、DataObjectFactoryの生成時にどのタイプのオブジェクトを生成するか
を一度だけ指定します。それ以降は、create()メソッドを呼び出すだけで、再びタイプを指定せずに何
度でもオブジェクトを生成できるようになります。




                                                                  81
82
83
84
◆アブストラクトファクトリーのメリット
パターン適用後の設計には、次のようなメリットがあります。
・クライアントから具体的なクラスを隠蔽する
クライアントは部品オブジェクトの具体的なクラスを意識する必要がありません。抽象部品クラスのイ
ンターフェースを介して部品オブジェクトにアクセスするので、具体的な部品クラスが変わっても、呼
び出し側を変更する必要がありません。
・部品をグループ化する
一緒に使用すべき部品の生成処理をひとまとめにすることができます。その結果、一緒に使用すべ
きでない部品どうしを誤って組み合わせることがなくなります。
・部品のグループを容易に変更できる
クライアント側は抽象的な生成方法と部品だけを意識するので、どのセットを生成するかを簡単に変
更できます。




                                                 85
◆アブストラクトファクトリーの構成
アブストラクトファクトリーはその名のとおり「抽象的な工場」を設けます。このパターンでは工場とそこ
で作る部品を抽象化し、具体的な生成方法と部品をクライアント側から隠蔽します。その結果、クライ
アント側は具体的な生成方法と部品を意識せず、どのような種類の部品でも同じように対応できるよ
うになります。
抽象化した部品はインターフェースとして定義します。各インターフェースは継承することを前提とし
ていますので、メソッドはVirtual宣言を行い、さらに実体は子クラスで実装するため純粋仮想関数とし
て宣言します。
次に、具体的な部品クラスをこれらのクラスを実装して定義します。
次に、抽象的な部品を生成する工場のクラスを定義します。これもVirtual宣言を行い、インターフェー
スとして定義します。これは抽象的な部品オブジェクトを生成するメソッドを定義したクラスです。この
段階では具象クラスがどんな部品なのかということは関知せず、組み合わせるべき抽象化された部
品を生成するメソッドを定義します。
さらにインターフェースを実装して、具体的な部品ごとに、作成するファクトリークラスを定義します。




                                                     86
◆テンプレートメソッドのメリット
・流れを把握しやすい
処理の流れはテンプレートメソッドで定義されているので、テンプレートメソッドを見れば大筋の流れ
がすぐにわかります。また、たとえば3パターンの処理をテンプレートメソッドから継承した場合、それ
ぞれが1つの同じ流れであることがわかるので、それぞれを別々に理解する手間が省けます。テンプ
レートメソッドを用していない場合には、ソースコードを丹念に読まなければ同じ流れで処理している
ものが存在するかどうかを知ることができません。
・カスタマイズポイントが明確である
テンプレートメソッドパターンを使用すると、メソッドのオーバーライドが強制されます。このオーバーラ
イドを強制されるメソッドが、カスタマイズ可能な部分になります。逆に言えば、カスタマイズ時にはそ
れ以外の部分を考えなくてよいということです。これにより、詳細の実装を変えなければいけない箇
所はどこで、考えなくてよい箇所はどこかを明雄に示すことができます。




                                                   87
◆テンプレートメソッドの構成
3つの処理の流れはほぼ同じですが、具体的な処理内容は異なります。このように、処理の大筋の
流れは一緒でも個別の処理は異なる、というケースでテンプレートメソッドが役に立ちます。
上記スライドの処理は、いずれも以下の手順で行われています。
1.ファイルからデータを読み込む
2. データを整形する
3.整形したデータを出力する
この流れをFileFormatterという抽象クラスで定義します。
仮にformatter()というメソッドをテンプレートメソッドとして定義します。このメソッドが1から3の処理の
流れを定義(=テンプレートを提供)しています。テンプレートメソッドの中で呼び出すメソッドは、基本的
には純粋仮想関数として定義しておきます。こうすることで、このクラスを継承したサブクラス側にメ
ソッドのオーバーライドを強制することができます。
具体的な処理は、このFileFormatter抽象クラスを継承したサブクラス内で実装します




                                                          88
◆イテレータパターンのメリット
イテレータパターンを適用すると、集約オブジェクト内のオブジェクトに順次アクセスするときに、次の
決まった手順を使うことになります。
1. Iteratorオブジェクトをiterator()メソッドで取得する
2. IteratorオブジェクトのhasNext()メソッドで次のオブジェクトが存在するか確認する
3. 次のオブジェクトが存在すれば、Iteratorオブジェクトのnext()メソッドで次のオブジェクトを取得する
このようにパターンを適用した場合は、Machineクラスを変更しでも、Iteratorオブジェクトによる統一
化されたメソッドを利用している限り、クライアント側のコードはいっさい変更する必要がありません。




                                                            89
集約オブジェクトに格納されるオブジェクトはPartsで、これを複数保持して集約しているのがMachine
クラスです。
Machineクラスはオブジェクトへの順次アクセスを統一的に行うためにAggregateインターフェースを実
装し、iterator()を実装します。実際に順次アクセスを行うのはIteratorMachineクラスです。
IteratorMachineクラスは順次アクセスの手順を統一化するために、hasNext()とnext()を宣言している
Iteratorインターフェースを実装しています。




                                                                90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
基本的な流れは次のようになっています。
1.socket関数
リクエストを受け付けるためのソケットを作成します。
2.bind関数
サーバーのアドレス情報(IPアドレス及びポート番号)をソケットに結び付けます。
3.listen関数
リクエストの接続待ちキューを設定し、接続要求の準備をします。
4.accept関数
接続待ちのリクエストを受付けて接続を確立し、新しいソケットを作成します。

accept関数により新しく生成されたソケットは、 通信専用のソケットで、send関数及びrecv関
数によりデータの送受信ができます。 これらの関数は、クライアントアプリケーションでも使わ
れるので、後程まとめて解説します。




                                                     108
socket関数の使い方
TCPのソケットを生成するときは、通常次のような記述をします。

SOCKET s=socket(AF_INET,SOCK_STREAM,0);
if(s==INVALID_SOCKET){ printf("ソケットを生成できません");
 exit(1);
} /* 以下、bindへ続く */

ソケットの生成は以上で完了です。




                                                 109
bind関数の使い方
bindを使ってソケットにアドレス情報を結び付けるには次のような記述をします。
  SOCKADDR_IN sain;
  sain.sin_family=AF_INET;
  sain.sin_addr.s_addr=INADDR_ANY;
  sain.sin_port=htons(port_number);
  if(bind(s,(SOCKADDR*)&sain,sizeof(sain)!=0){
     printf("バインドに失敗しました");
     exit(1);
  }
  /* 以下、listenへ続く */
ソケットへアドレス情報を結び付ける作業は以上で終了です。 なお、上で出てきたhtons関数はコン
ピュータの数値表現をネットワークの数値表現に変更するものです。 リトルエンディアンをビッグデン
ディアンに変更します。




                                                   110
listen関数の使い方
  if(listen(s,10)!=0){
     printf("listenに失敗しました。");
     exit(1);
  }
  /* 以下、accept へ続く */




                                 111
accept関数の使い方
 SOCKET t;
 SOCKADDR_IN ta;
 int ta_len;

 ta_len=sizeof(ta);
 t=accept(s,&ta,&ta_len);
 if(t==INVALID_SOCKET){
    printf("接続が確立できませんでした。");
    exit(1);
 }
 /* 以下、send関数及びrecv関数を使って送受信操作ができる */
接続待ちキューにリクエストがなかった場合、 accept関数を実行するとプログラムはここでブロックし
ます。
そして接続要求があると、ここから動作を再開します。




                                                     112
普通の状態では、recvやrecvfromはデータが受信できるまでブロッキングします。 ソケットを一つしか
利用していない場合にはブロッキングは非常に便利なのですが、ソケットが複数になると困ってしま
います。 複数のソケットを扱うとき、片方のソケットでブロッキングしたままになってしまうと他のソケッ
トにデータが到着しても受信が出来なくなってしまいます。




                                                        113
114
115
116
connect関数の使い方
inet_addr関数は、IPアドレスをIN_ADDR構造体に適したアドレス形式に変換します。gethostbyname
関数はDNSサーバーに問い合わせて、ドメインからIPアドレスを取得する操作を行います。
gethostbyname関数を実行するとhostent構造体へのポインタが返ります。 この構造体の中に接続先
のIPアドレスがあるので、これを利用してアドレス情報を作成します。
#include <stdio.h>
#include <winsock2.h>
int main( void ){
  int sock; struct sockaddr_in addr; int ret ; struct hostent *hostinfo;
  unsigned long inetaddress; char *hostname = "localhost";
  WSADATA wsadata;
  WSAStartup( 0x0002, &wsadata );
  inetaddress = inet_addr( hostname );
  if ( inetaddress == INADDR_NONE ) {
    hostinfo = gethostbyname( hostname );
    if ( hostinfo == 0 ) { return -1; }// ホスト名解決に失敗
    inetaddress = *(unsigned long *)hostinfo->h_addr_list[0];
  }
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = inetaddress;
  addr.sin_port = htons(7000);
  sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
  ret = connect( sock, (struct sockaddr *)&addr, sizeof addr );
  if ( ret < 0 ) { printf( "localhost 7000 に接続できなかった" ); return 0; }
  printf( "localhost 7000 に接続できた" ); closesocket( sock ); return 1;
}


                                                                           117
send関数の使い方
文字列"Hello¥r¥n"を送信する場合は次のようになります。
  int ok;
  const char* st="Hello¥r¥n";

ok=send(s,st,7,0);
if(ok==SOCKET_ERROR){
   printf("送信できませんでした。");
   exit(1);
}




                                   118
recv関数の使い方
recv関数は受信長が必ずしもlenまで達しているとは限りません。 そこで、recv関数を使って、lenまで
受信する関数receiveを紹介します。

int receive(SOCKET s,char* buf,int* len){
   int revd_size;
   int tmp;
   revd_size=0;
   while(revd_size<*len){
     tmp=recv(s,buf+revd_size,*len-revd_size,0);
     if(tmp==SOCKET_ERROR){ /* エラーが発生 */
        *len=received;
        return SOCKET_ERROR;
     }
     if(tmp==0){     /* ソケットが切断された */
        *len=received;
        return 0;
     }
     received+=tmp;
   }
   *len=received;
   return received;
}
このreceive関数は、lenまで受信するかソケットが閉じられるまでrecv関数を呼び続けます。 返り値は
recv関数と同じです。しかし、読み込みの途中でソケットが閉じられた場合を想定して、 引き数lenは
ポインタとし、ここに受信したデータ長を返すようにしてあります。


                                                         119
ws2_32.libは$(WindowsSdkDir)¥ws2_32.libに存在しています。指定はws2_32.libでかまいません。
プロジェクトのプロパティ>構成プロパティ>リンカ>入力>追加の依存ファイルで設定を行
います。




                                                                       120
WSAStartupでWinsockのライブラリのバージョン指定をします
MAKEWORD(2,0)はWinsock2.0を使うことを示します
Winsockライブラリを読み込むことで以降のソケット関係の関数を使用することができます




                                               121
122
123
124
SQLiteのサイトからソースコードおよびコンパイル済のDLLが入手可能
通常はアプリケーションで利用するにはソースコードをコンパイルしライブラリを作らなければならな
い
ダウンロード・ページから、
  sqlite3_amalgamation-####.zip(ソースコード、ヘッダ、DEFファイル)
  sqlite3_dll-####.zip(DLL)
の2つを入手します(####にはバージョン番号が付加されています)

得られたDLLとDEFからインポート・ライブラリ(LIB)を生成しましょう。
「sqlite3.dll」と「sqlite3.def」を適当なディレクトリに置き、コマンドプロンプトから、
lib /VERBOSE /MACHINE:I386 /DEF:sqlite3.def /OUT:sqlite3.lib /NAME:sqlite3.dll
  を実行することでインポート・ライブラリ「sqlite3.lib」が生成されます。
ユーザーコードのコンパイル時に「sqlite3.h」、リンク時に「sqlite3.lib」、実行時に「sqlite3.dll」が使わ
れることになります。




                                                                                 125
SQL文に記述された値の記述方法からその値のデータ型を決めています。例えば「'」で囲まれていれ
ばTEXT型、小数点も指数も無ければINTEGER型、小数点か指数があればREAL型、などです。




                                                   126
127
128
上記のように、データベース・ファイルのパスとデータベース・ハンドル(sqlite3*)のポインタを与えま
す。指定したファイルが存在しないときは新規に作成されます。データベース・ファイルパスに
":memory:"を指定するとデータベースがメモリ内に作られ、アプリケーション実行時にのみ有効な揮
発性データベースとして使えます。

戻り値は処理の結果を表し、SQLITE_OKであれば成功、失敗時にはエラーコードが返されます。最後
に呼び出された関数の結果に対応するエラーメッセージはconst char* sqlite3_err_msg()で取得でき
ます。

sqlite3* db;
int result = sqlite3_open(":memory:", &db);
if ( result != SQLITE_OK ) {
  cerr << sqlite3_errmsg() << endl;
  return;
}

◆open
引数filenameは、sqlite3_open()とsqlite3_open_v2()ではUTF-8、sqlite3_open16()ではUTF-16として、
ネイティブのバイトオーダーで解釈されます。
・データベースを(生成して)開くことに成功した場合、SQLITE_OKが返されます。
・それ以外の場合はerror codeを返します。
・データベースのデフォルトのエンコーディングは、sqlite3_open()とsqlite3_open_v2()を呼び出す場合
はUTF-8、sqlite3_open16()を使用する場合はネイティブのバイトオーダーでUTF-16になります。
注意:現在定義されているコードページに関わらず、sqlite3_open()とsqlite3_open_v2()の引数
filenameに使用するエンコーディングはUTF-8にする必要があります。ファイル名が国際文字を含む
場合は、sqlite3_open()またはsqlite3_open_v2()に渡す前にUTF-8に変換する必要があります。


                                                                                   129
◆sqlite3_open_v2()
sqlite3_open_v2()インターフェイスは、新しいデータベース接続を介して追加制御のため
に2つのパラメータを追加を受け取る以外は、sqlite3_open()のように動作します。
・sqlite3_open_v2()のフラグパラメータは下記の3つの内の1つを指定し、オプションで
SQLITE_OPEN_NOMUTEX、SQLITE_OPEN_FULLMUTEX、SQLITE_OPEN_SHAREDCACHE、
SQLITE_OPEN_PRIVATECACHEフラグを結合します。
◎SQLITE_OPEN_READONLY
データベースを読み取り専用モードで開きます。
データベースが既に存在しない場合はエラーを返します。
◎SQLITE_OPEN_READWRITE
データベースを読み書き可能モードで開きます。
オペレーティングシステムによってファイルが書き込み保護されている場合は読み取り
専用として開きます。
どちらの場合もデータベースが既に存在している必要があり、存在しない場合はエラー
を返します。
◎SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
データベースを読み書き可能モードで開き、既に存在しない場合は生成します。
これはsqlite3_open()とsqlite3_open16()のデフォルトの動作です。
・追加のフラグ
◎SQLITE_OPEN_NOMUTEXフラグを設定した場合、コンパイル時または起動時にシング
ルスレッドモードに設定されていない限り、threading modeをマルチスレッドでデータ
ベース接続を開きます。
◎SQLITE_OPEN_FULLMUTEXフラグを設定した場合、コンパイル時または起動時に予め
シングルスレッドを選択していない限り、threading modeをシリアライズでデータベース
接続を開きます。
◎SQLITE_OPEN_SHAREDCACHEフラグは、sqlite3_enable_shared_cache()を使用して共
有キャッシュが有効になっているかどうかに関わらず、shared cache modeを使用して適
格なデータベース接続をもたらします。
◎SQLITE_OPEN_PRIVATECACHEフラグは、たとえshared cache modeが有効であっても、
共有しないデータベース接続をもたらします。
・4番目のパラメータは、データベース接続が使うであろう、オペレーティングシステムの
インターフェイスを定義したsqlite3_vfsオブジェクトの名前になります。NULL指定の場合
は、デフォルトのsqlite3_vfsが使用されます。




                                                                     129
SQLの実行は大きく2つのフェーズ「prepare」と「step」に分かれます。「prepar」ではSQL文をあらかじめ
コンパイル(構文解釈)し、実行に備えます。

zSqlに与えたSQL文がコンパイルされ、ステートメント・ハンドル(sqlite3_stmt*)が*ppStmtに出力され
ます。nByteは文字数ではなくバイト数であることに留意してください(-1とすればSQL文が'¥0'終端され
ているとみなします)。

SQLの実行はステートメント・ハンドルに対して行われます。




                                                                130
ステートメント・ハンドルの廃棄を怠ると、リソースリークによりプログラムの動作に影響が発生します。




                                               131
sqlite3_prepare_v2の定義は以下の通りです。
int sqlite3_prepare_v2(
  sqlite3 *db,       /* データベースハンドル*/
  const char *zSql,    /* SQLステートメント(UTF-8エンコード) */
  int nByte,        /* zSqlの文字列長 */
  sqlite3_stmt **ppStmt, /* OUT: Statement handle */
  const char **pzTail /* OUT: Pointer to unused portion of zSql */
);
const char* command = "DROP TABLE price_list;"
                        "CREATE TABLE price_list ( item TEXT, price INTEGER);";
この処理は1つの文字列に複数のSQLを含めています。




                                                                                  132
◆?NNN
-- SQL
INSERT INTO tower ( name, height ) VALUES ( ?111, ?222 );

/* API */
sqlite3_bind_text( stmt, 111, "東京スカイツリー", -1, SQLITE_STATIC );
sqlite3_bind_int( stmt, 222, 634 );

-- 実行される処理
INSERT INTO tower ( name, height ) VALUES ( '東京スカイツリー', 634 );

プレースホルダが'?番号'のときは、sqlite3_bind関数で指定した位置はその番号とする。番号は1から
999(デフォルト)の間でなければならない。上の例では、プレースホルダが?111, ?222なので、
sqlite3_bind_textの引数では111、sqlite3_bind_intの引数では222を指定している。

◆@VVV
プレースホルダは'記号+名称'で設定しても良い。記号は:, @, $のいずれかを使用する。ただしパラ
メータの位置を設定する引数はint型のため、パラメータの名称からSQL文中の位置を割り出す関数
が必要になる。
その際にsqlite3_bind_parameter_indexを使用する。これはプリペアードステートメントとプレースホル
ダを引数とし、見つかればその位置を戻り値とする。位置が見つからないときの戻り値は0で、これは
パラメータの位置としては無効な値となる。
注:同じ名称のプレースホルダが1つのSQL文中に複数含まれているときは、それぞれの箇所に同じ
値が設定される。

'記号+名称'のとき(例)


                                                                 133
-- SQL
INSERT INTO tower ( name, height ) VALUES ( @name, @height );

/* API */
sqlite3_bind_text( stmt, sqlite3_bind_parameter_index( stmt, "@name" ), "東京スカイツ
リー", -1, SQLITE_STATIC );
sqlite3_bind_int( stmt, sqlite3_bind_parameter_index( stmt, "@height" ), 634 );

-- 実行される処理
INSERT INTO tower ( name, height ) VALUES ( '東京スカイツリー', 634 );




                                                                                  133
引数は以下のとおりです。
1. ステートメント・ハンドル
2. プレースホルダの位置(最初のプレースホルダを1とする)
3. バインド値
4. バインド値のバイト数
5. デストラクタ……実行完了時にバインド値を引数として呼び出される関数へのポインタ。バインド値
   が実行中に変化しないのであればSQLITE_STATIC、バインド値のコピーをステートメントが保持す
   るならSQLITE_TRANSIENTを指定できます。




                                                        134
135
SQL文がSELECTのように複数(0個以上)の結果を返すとき、sqlite3_step()を何度も呼び出すことでそ
の結果が得られますが、sqlite3_step()は結果の個数だけSQLITE_ROW、そして最後にSQLITE_DONE
を返します。
結果の取得は、sqlite3_column_*()にステートメント・ハンドルと何列目のカラムか(0起点)を指定する
ことで得られます。
これらのルーチンは、クエリの現在の結果行の単一列に関する情報を返します。
◆引数
全ての関数の第1引数は評価されるprepared statementのポインタ(sqlite3_prepare_v2()から返され
るsqlite3_stmt*)で、第2引数は取得したい列のインデックスです。
・結果セットの左端の列のインデックスは0です。
・結果セットの列数は、sqlite3_column_count()を使用して決定することができます。
・SQLステートメントが現在有効な行を指していない、または列のインデックスが範囲外の場合、結果
は未定義になります。
・これらのルーチンは、最新のsqlite3_step()の呼び出しでSQLITE_ROWが返された時のみ呼び出され
ます。
・列の型を確認する必要がある場合、sqlite3_column_type()ルーチンを使用すると、データ型のコー
ドが返されます。
戻り値は、SQLITE_INTEGER、SQLITE_FLOAT、SQLITE_TEXT、SQLITE_BLOB、またはSQLITE_NULLのいず
れかになります。
◎結果がBLOBまたはUTF-8文字列の場合、sqlite3_column_bytes()によってバイト数を取得できます。
◎結果が数値の場合、sqlite3_column_bytes()はsqlite3_snprintf()によりUTF-8文字列に変換され、文
字列のバイト数を返します。
◎結果がNULLの場合、sqlite3_column_bytes()はゼロを返します。
◎sqlite3_column_bytes()によって返される値は、文字列の末端にあるゼロ終端を含みません。
◎sqlite3_column_text()によって返される文字列は空の文字列と同様に常にゼロ終端です。



                                                                             136
137
◆sqlite3_column_type()を用いたsqlite3_column_*()の実行
sqlite3_column_type()の結果をswitchで場合分けし、それに応じてデータ型ごとのsqlite3_column_*()
が実行される。




                                                                        138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
CREATE TABLE EMP
(
   EMPNO NUMBER(4,0) NOT NULL,
   ENAME VARCHAR2(10),
   JOB   VARCHAR2(9),
   MGR    NUMBER(4,0),
   HIREDATE DATE,
   SAL   NUMBER(7,2),
   COMM NUMBER(7,2),
   DEPTNO NUMBER(2,0),
   PRIMARY KEY (EMPNO)
);

CREATE TABLE DEPT
(
   DEPTNO NUMBER(2,0),
   DNAME VARCHAR2(16),
   LOC    VARCHAR2(10),
   PRIMARY KEY (DEPTNO)
);




                                 167
INSERT INTO DEPT (DEPTNO,DNAME,LOC) VALUES('10','ACCOUNTING','NEW YORK');
INSERT INTO DEPT (DEPTNO,DNAME,LOC) VALUES('20','RESEARCH','DALLAS');
INSERT INTO DEPT (DEPTNO,DNAME,LOC) VALUES('30','SALES','CHICAGO');
INSERT INTO DEPT (DEPTNO,DNAME,LOC) VALUES('40','OPERATIONS','BOSTON');

INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)
VALUES('7369','SMITH','CLERK','7902','1980-12-17','800','','20');
INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)
VALUES('7499','ALLEN','SALESMAN','7698','1981-02-20','1600','300','30');
INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)
VALUES('7521','WARD','SALESMAN','7698','1981-02-22','1250','500','30');
INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)
VALUES('7566','JONES','MANAGER','7839','1981-04-02','2975','','20');
INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)
VALUES('7654','MARTIN','SALESMAN','7698','1981-09-28','1250','1400','30');
INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)
VALUES('7698','BLAKE','MANAGER','7839','1981-05-01','2850','','30');
INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)
VALUES('7782','CLARK','MANAGER','7839','1981-06-09','2450','','10');
INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)
VALUES('7788','SCOTT','ANALYST','7566','1987-04-19','3000','','20');
INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)
VALUES('7839','KING','PRESIDENT','','1981-11-17','5000','','10');
INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)
VALUES('7844','TURNER','SALESMAN','7698','1981-09-08','1500','0','30');
INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)


                                                                             168
VALUES('7876','ADAMS','CLERK','7788','1987-05-23','1100','','20');
INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)
VALUES('7900','JAMES','CLERK','7698','1981-12-03','950','','30');
INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)
VALUES('7902','FORD','ANALYST','7566','1981-12-03','3000','','20');
INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)
VALUES('7934','MILLER','CLERK','7782','1982-01-23','1300','','10');




                                                                      168
SELECT ENAME,SAL FROM EMP WHERE SAL = (SELECT SAL FROM EMP WHERE ENAME = 'SCOTT');

SELECT deptno,ename,sal FROM emp WHERE sal = (SELECT MAX(sal) FROM emp);




                                                                                     169
sqliteでは明示的なトランザクションを実行すると性能が向上します。

◆ロールバックする例
BEGIN TRANSACTION;
INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)
 VALUES('1112','MIKU','CLERK',7902,'2009-09-30','800',NULL,'20');
ROLLBACK;
SELECT * FROM EMP;
7369|SMITH|CLERK|7902|1980-12-17|800||20
(中略)※MIKUは表示されない

◆コミットできる例
BEGIN TRANSACTION trn1;
INSERT INTO EMP
    (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)
 VALUES('1112','MIKU','CLERK',7902,'2009-09-30','800',NULL,'20');
COMMIT TRANSACTION trn1;
SELECT * FROM EMP;
(中略)
1112|MIKU|CLERK|7902|2009-09-30|800||20




                                                                    170

Weitere ähnliche Inhalte

Andere mochten auch

Andere mochten auch (20)

Swot analysis
Swot  analysisSwot  analysis
Swot analysis
 
Produce pakpoultry
Produce pakpoultryProduce pakpoultry
Produce pakpoultry
 
המשמר החברתי ופעילותו
המשמר החברתי ופעילותוהמשמר החברתי ופעילותו
המשמר החברתי ופעילותו
 
Śniadanie Daje Moc
Śniadanie Daje MocŚniadanie Daje Moc
Śniadanie Daje Moc
 
Conferencia
ConferenciaConferencia
Conferencia
 
Alcanzando el exito escolar ebenezer
Alcanzando el exito escolar ebenezerAlcanzando el exito escolar ebenezer
Alcanzando el exito escolar ebenezer
 
DRR Concept
DRR ConceptDRR Concept
DRR Concept
 
201211_모바일 포털을 지향하는 카카오톡_KT경제경영연구소
201211_모바일 포털을 지향하는 카카오톡_KT경제경영연구소201211_모바일 포털을 지향하는 카카오톡_KT경제경영연구소
201211_모바일 포털을 지향하는 카카오톡_KT경제경영연구소
 
Profarma apimec 3_t10
Profarma apimec 3_t10Profarma apimec 3_t10
Profarma apimec 3_t10
 
Extra cs1
Extra cs1Extra cs1
Extra cs1
 
Tema 4 hc
Tema 4 hcTema 4 hc
Tema 4 hc
 
Cd制作について
Cd制作についてCd制作について
Cd制作について
 
SensesClub - Platinum booklet
SensesClub - Platinum bookletSensesClub - Platinum booklet
SensesClub - Platinum booklet
 
Apresentação Reunião Pública - Maio 2008
Apresentação Reunião Pública - Maio 2008Apresentação Reunião Pública - Maio 2008
Apresentação Reunião Pública - Maio 2008
 
Śniadanie Daje Moc
Śniadanie Daje MocŚniadanie Daje Moc
Śniadanie Daje Moc
 
храбрый опёнок. э.шим
храбрый опёнок. э.шимхрабрый опёнок. э.шим
храбрый опёнок. э.шим
 
8º balanço do PAC 2
8º balanço do PAC 28º balanço do PAC 2
8º balanço do PAC 2
 
Ahorra energía eléctrica
Ahorra energía eléctricaAhorra energía eléctrica
Ahorra energía eléctrica
 
Śniadanie Daje Moc
Śniadanie Daje MocŚniadanie Daje Moc
Śniadanie Daje Moc
 
Notas g82 p y cuadro de honor 2p1s
Notas g82 p y cuadro de honor 2p1sNotas g82 p y cuadro de honor 2p1s
Notas g82 p y cuadro de honor 2p1s
 

Ähnlich wie Cpp v3

Javascripでオブジェクト指向
Javascripでオブジェクト指向Javascripでオブジェクト指向
Javascripでオブジェクト指向1000 VICKY
 
WSDM2018 読み会 Latent cross making use of context in recurrent recommender syst...
WSDM2018 読み会 Latent cross making use of context in recurrent recommender syst...WSDM2018 読み会 Latent cross making use of context in recurrent recommender syst...
WSDM2018 読み会 Latent cross making use of context in recurrent recommender syst...Takanori Nakai
 
Cloud principles and paradigms kimtea-2010-04-24
Cloud principles and paradigms kimtea-2010-04-24Cloud principles and paradigms kimtea-2010-04-24
Cloud principles and paradigms kimtea-2010-04-24Kazuki Aranami
 
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...Building asp.net core blazor and elasticsearch elasticsearch using visual stu...
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...Shotaro Suzuki
 
オブジェクト指向入門6
オブジェクト指向入門6オブジェクト指向入門6
オブジェクト指向入門6Kenta Hattori
 
"Hello World!" から始める Calc で LibreOffice Basic
"Hello World!" から始める Calc で LibreOffice Basic"Hello World!" から始める Calc で LibreOffice Basic
"Hello World!" から始める Calc で LibreOffice Basic78tch
 
平成24年度社会知能情報学専攻修士論文中間発表会(予稿)
平成24年度社会知能情報学専攻修士論文中間発表会(予稿)平成24年度社会知能情報学専攻修士論文中間発表会(予稿)
平成24年度社会知能情報学専攻修士論文中間発表会(予稿)n-yuki
 
オブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツオブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツ増田 亨
 
DSL駆動によるクラウド・アプリケーション開発
DSL駆動によるクラウド・アプリケーション開発DSL駆動によるクラウド・アプリケーション開発
DSL駆動によるクラウド・アプリケーション開発Tomoharu ASAMI
 
情報編集(Web) HTML5 実践3 Processingによるデータの可視化と生成的表現
情報編集(Web) HTML5 実践3 Processingによるデータの可視化と生成的表現情報編集(Web) HTML5 実践3 Processingによるデータの可視化と生成的表現
情報編集(Web) HTML5 実践3 Processingによるデータの可視化と生成的表現Atsushi Tadokoro
 
What is RDRA
What is RDRAWhat is RDRA
What is RDRAzenkan
 
中規模Androidアプリ開発の過程に生じた問題と対策の紹介
中規模Androidアプリ開発の過程に生じた問題と対策の紹介中規模Androidアプリ開発の過程に生じた問題と対策の紹介
中規模Androidアプリ開発の過程に生じた問題と対策の紹介NilOne Ltd.
 
実はとても面白い...Documentation library
実はとても面白い...Documentation library実はとても面白い...Documentation library
実はとても面白い...Documentation libraryKouta Shiobara
 
Real World Azure RBAC
Real World Azure RBACReal World Azure RBAC
Real World Azure RBACToru Makabe
 
PHP基礎勉強会
PHP基礎勉強会PHP基礎勉強会
PHP基礎勉強会Yuji Otani
 
VSUG Day 2010 Summer - Using ADO.NET Entity Framework
VSUG Day 2010 Summer - Using ADO.NET Entity FrameworkVSUG Day 2010 Summer - Using ADO.NET Entity Framework
VSUG Day 2010 Summer - Using ADO.NET Entity FrameworkAtsushi Fukui
 
Creating and Using Links between Data Objects
Creating and Using Links between Data ObjectsCreating and Using Links between Data Objects
Creating and Using Links between Data ObjectsMitsuo Yamamoto
 
Azure Antenna AI 概要
Azure Antenna AI 概要Azure Antenna AI 概要
Azure Antenna AI 概要Miho Yamamoto
 

Ähnlich wie Cpp v3 (20)

Javascripでオブジェクト指向
Javascripでオブジェクト指向Javascripでオブジェクト指向
Javascripでオブジェクト指向
 
WSDM2018 読み会 Latent cross making use of context in recurrent recommender syst...
WSDM2018 読み会 Latent cross making use of context in recurrent recommender syst...WSDM2018 読み会 Latent cross making use of context in recurrent recommender syst...
WSDM2018 読み会 Latent cross making use of context in recurrent recommender syst...
 
Cloud principles and paradigms kimtea-2010-04-24
Cloud principles and paradigms kimtea-2010-04-24Cloud principles and paradigms kimtea-2010-04-24
Cloud principles and paradigms kimtea-2010-04-24
 
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...Building asp.net core blazor and elasticsearch elasticsearch using visual stu...
Building asp.net core blazor and elasticsearch elasticsearch using visual stu...
 
オブジェクト指向入門6
オブジェクト指向入門6オブジェクト指向入門6
オブジェクト指向入門6
 
"Hello World!" から始める Calc で LibreOffice Basic
"Hello World!" から始める Calc で LibreOffice Basic"Hello World!" から始める Calc で LibreOffice Basic
"Hello World!" から始める Calc で LibreOffice Basic
 
平成24年度社会知能情報学専攻修士論文中間発表会(予稿)
平成24年度社会知能情報学専攻修士論文中間発表会(予稿)平成24年度社会知能情報学専攻修士論文中間発表会(予稿)
平成24年度社会知能情報学専攻修士論文中間発表会(予稿)
 
オブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツオブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツ
 
DSL駆動によるクラウド・アプリケーション開発
DSL駆動によるクラウド・アプリケーション開発DSL駆動によるクラウド・アプリケーション開発
DSL駆動によるクラウド・アプリケーション開発
 
情報編集(Web) HTML5 実践3 Processingによるデータの可視化と生成的表現
情報編集(Web) HTML5 実践3 Processingによるデータの可視化と生成的表現情報編集(Web) HTML5 実践3 Processingによるデータの可視化と生成的表現
情報編集(Web) HTML5 実践3 Processingによるデータの可視化と生成的表現
 
分散表現を用いたリアルタイム学習型セッションベース推薦システム
分散表現を用いたリアルタイム学習型セッションベース推薦システム分散表現を用いたリアルタイム学習型セッションベース推薦システム
分散表現を用いたリアルタイム学習型セッションベース推薦システム
 
What is RDRA
What is RDRAWhat is RDRA
What is RDRA
 
概念モデリング再考
概念モデリング再考概念モデリング再考
概念モデリング再考
 
中規模Androidアプリ開発の過程に生じた問題と対策の紹介
中規模Androidアプリ開発の過程に生じた問題と対策の紹介中規模Androidアプリ開発の過程に生じた問題と対策の紹介
中規模Androidアプリ開発の過程に生じた問題と対策の紹介
 
実はとても面白い...Documentation library
実はとても面白い...Documentation library実はとても面白い...Documentation library
実はとても面白い...Documentation library
 
Real World Azure RBAC
Real World Azure RBACReal World Azure RBAC
Real World Azure RBAC
 
PHP基礎勉強会
PHP基礎勉強会PHP基礎勉強会
PHP基礎勉強会
 
VSUG Day 2010 Summer - Using ADO.NET Entity Framework
VSUG Day 2010 Summer - Using ADO.NET Entity FrameworkVSUG Day 2010 Summer - Using ADO.NET Entity Framework
VSUG Day 2010 Summer - Using ADO.NET Entity Framework
 
Creating and Using Links between Data Objects
Creating and Using Links between Data ObjectsCreating and Using Links between Data Objects
Creating and Using Links between Data Objects
 
Azure Antenna AI 概要
Azure Antenna AI 概要Azure Antenna AI 概要
Azure Antenna AI 概要
 

Cpp v3