マルチな時代の設計と開発 駆け足で PART(3,4),5,6

Slides:



Advertisements
Similar presentations
1 情報基礎 A 第 9 週 プログラミング入門 VBA の基本文法 1 準備・変数・データの入出力 徳山 豪・全 眞嬉 東北大学情報科学研究科 システム情報科学専攻 情報システム評価学分野.
Advertisements

1 なんとなく Ajax ~新しくて古い XMLHttp 川合孝典 (Kansai.pm) 2005/5/22.
Web アプリをユーザー毎に カスタマイズ可能にする AOP フレームワーク
.NET Framework 4.0 世代の Expression Trees
匠の伝承 マルチな時代の設計と開発.
DB(データベース)のおはなし 作成者:小野正広 DBと言っても、  ドラゴンボール ではないですぞ! 3/1/2017.
情報理工学部 情報システム工学科 ラシキアゼミ 3年 H 井奈波 和也
情報理工学部 情報システム工学科 3年 H 井奈波 和也
TMenu メニューバーを用いた操作のための コンポーネント.
S2Container.NET, S2Dao.NET コミッタ 藤井 宏明
匠の伝承w マルチな時代の設計と開発 パート3.
CakePHPを業務に導入する Shin x blog 新原 雅司.
Win32APIとMFC H107102 古田雅基 H107048 佐藤一樹 H107126 山下洋平.
情報理工学部 情報システム工学科 ラシキアゼミ3年 H 岡田 貴大
コンポーネントの再利用に必要な情報 えムナウ (児玉宏之)
コンポーネントの再利用に必要な情報 えムナウ (児玉宏之)
実行時のメモリ構造(1) Jasminの基礎とフレーム内動作
VBA H106077 寺沢友宏.
プログラミング演習II 2004年10月19日(第1回) 理学部数学科・木村巌.
匠の伝承w マルチな時代の設計と開発 パート2.
Bottle/Pythonによる Webアプリ入門
RAD Studio 14/09/27 TEffectを使った綺麗なForm
Day3 Day4 Day3 Day4.
C#とC++とオブジェクト指向 上甲 健史.
(B2) 親: minami, kazuki 多様な認証機器に対応する 認証システム (B2) 親: minami, kazuki.
データベース設計 第9回 Webインタフェースの作成(1)
マイクロソフト Access での SQL 演習 第1回 SQL問い合わせ(クエリ)
マイクロソフト Access を使ってみよう 第4回
C++とオブジェクトデータベース入門 8.オブジェクトデータベースとは 森井 喬 Webページ
第8章 Web技術とセキュリティ   岡本 好未.
Cプログラミング演習 中間まとめ2.
第2回.リレーショナルデータベース入門 SQL を用いたテーブルへの行の挿入 SQL 問い合わせの発行と評価結果の確認.
第1回.リレーショナルデータベースを使ってみよう
第1回.リレーショナルデータベースを使ってみよう
第2回.リレーショナルデータベース入門 SQL を用いたテーブルへの行の挿入 SQL 問い合わせの発行と評価結果の確認.
0からわかるF# Part1 中 博俊 F# September 2008 CTP Base.
0からわかるF# Part1 中 博俊 F# September 2008 CTP Base.
匠の伝承w マルチな時代の設計と開発 パート7.
MVP for VB が語る C# 入門 初音 玲.
MVP for VB が語る C# 入門 初音 玲.
図書館職員のための アプリケーション開発講習会
暗黙的に型付けされる構造体の Java言語への導入
オブジェクト指向 プログラミング 第二回 知能情報学部 新田直也.
ローカル変数とグローバル変数 ローカル変数  定義された関数内だけで使用できる変数 グローバル変数 プログラム全体で使用できる変数.
第6回 2007年6月1日 応用Java (Java/XML).
50年前のプログラミング言語 50年後のプログラミング言語
0からわかるF# Part1 中 博俊 F# September 2008 CTP Base.
Nakano School of Business 経営情報ビジネス科 【 Java概論(Test5)】
0からわかるF# Part1 中 博俊 F# September 2008 CTP Base.
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
0からわかるF# Part1 中 博俊 F# September 2008 CTP Base.
0からわかるF# Part1 中 博俊 F# September 2008 CTP Base.
匠の伝承w マルチな時代の設計と開発 パート6.
情報基礎演習I(プログラミング) 第11回 7月12日 水曜5限 江草由佳
Webアプリケーションと JSPの基本 ソフトウェア特論 第4回.
プログラミング言語論 第十一回 理工学部 情報システム工学科 新田直也.
匠の伝承w マルチな時代の設計と開発 パート4.
サブゼミ第7回 実装編① オブジェクト型とキャスト.
匠の伝承w マルチな時代の設計と開発 パート7.
第5回 プログラミングⅡ 第5回
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
CO-Client Opeartion 1.1 利用履歴データベースの設計 (スキーマ バージョン 対応)
データベース第3回目 意味ごとにテーブルを分ける
JAVA入門⑥ クラスとインスタンス.
匠の伝承w マルチな時代の設計と開発 パート4.
ソフトウェア工学 知能情報学部 新田直也.
Javaとは Javaとはオブジェクト指向言語でJava VM(Java仮想マシン)と呼ばれるプログラム上で動作します。
プログラミング演習I 2003年6月11日(第9回) 木村巌.
応用Java(Java/XML) 第8回 2005年6月9日 植田龍男.
How To WPF アプリケーション Part3 By 中博俊.
Presentation transcript:

マルチな時代の設計と開発 駆け足で PART(3,4),5,6 匠の伝承w マルチな時代の設計と開発 駆け足で PART(3,4),5,6

スピーカー自己紹介 / \ / ─ ─\ ゆーちです。 / ,(●) (●)、\ ハンドル名です。 | (__人__) |     /      \    /  ─    ─\    ゆーちです。  /    ,(●) (●)、\   ハンドル名です。  |       (__人__)    |     \     ` ⌒´   /    本名は、内山康広といいます。 ,,.....イ.ヽヽ、___ ーーノ゙-、.   48歳です。 :   |  ‘; \_____ ノ.| ヽ I おっさんです。_| ̄|○     |  \/゙(__)\,|  i |      >   ヽ. ハ  |   ||  株式会社シーソフト代表取締役です。                  現役のエンジニアです。プログラム書いてます。 Becky!用 BkReplyer 2 よろしくお願いしますよ。ほんと。 にこにこカレンダーシートを販売しています。 2ちゃんねらーではありません。 Special thanks for 2ch.

前回までのおさらい /⌒ ⌒\ /( ●) (●)\ /::::::⌒(__人__)⌒:::::\      /⌒  ⌒\          /( ●)  (●)\   /::::::⌒(__人__)⌒:::::\   |     |r┬-|     | そんなのがあったのか?。    \      `ー'´     /

『モノ』に対する時間軸のイベントを列挙。 時間軸へのイベントが『状態』を作る。 開発は『状態』別に分けて考える。          ____           / ―  ―\ .     / (―)  (―)\    ・・・ちゃんとまじめな話をしたんだお。           /   ⌒(__人__)⌒ \     |      ` ―     |         \           /     ノ            \      /´               ヽ                |    l              \  ヽ    -一''''''"~~``'ー--、   -一'''''''ー-、.       ヽ ____(⌒)(⌒)⌒) )  (⌒_(⌒)⌒)⌒)) PART 1 開発者はプロセス指向にとらえがち。 オブジェクト指向は『モノ』をとらえる。 『モノ』に対する時間軸のイベントを列挙。 時間軸へのイベントが『状態』を作る。 開発は『状態』別に分けて考える。

処理の依存性を切り離す 非同期の事象はループを分断して考える。 イベントトレース図→状態遷移表。 ステートパターンの実装。 PART 2       ____      /⌒  ⌒\    /( >)  (<)\   /::::::⌒(__人__)⌒::::: \  ぐだぐだだったお。   |     /| | | | |     |   \  (、`ー―'´,    / 処理の依存性を切り離す 非同期の事象はループを分断して考える。 イベントトレース図→状態遷移表。 ステートパターンの実装。

クラスの依存性を少なくし独立性を高める。 PART4?なんだっけ・・・DIかな? では、PART5,6行きましょう!w          ____           / ―  ―\ .     / (―)  (―)\    デモをまじえて説明したんだお。           /   ⌒(__人__)⌒ \     |      ` ―     |         \           /     ノ            \      /´               ヽ                |    l              \  ヽ    -一''''''"~~``'ー--、   -一'''''''ー-、.       ヽ ____(⌒)(⌒)⌒) )  (⌒_(⌒)⌒)⌒)) PART 3 クラスに「時間軸」を考える。 オブザーバパターンによるイベント通知。 クラスの依存性を少なくし独立性を高める。 PART4?なんだっけ・・・DIかな? では、PART5,6行きましょう!w

いきなりですが。言語は何を使ってますか? Ada    Pascal          PHP            APL Scala          NC       Shakespeare        Whitespace     C++                     C                      Smalltalk             Java        C++     C++/CLI         UML       Objective-C  PostScript                        D言語         LISP       PL/I       アセンブラ       なでしこ                ActionScript                     F#          Tcl  SQL      Ruby        Visual Basic               Mind                 Delphi           / ̄ ̄ ̄\         Prolog  Grass            ./ ─    ─ \        FORTRAN                              /  <○>  <○>   \             COBOL          |     (__人__)     |          Modula-2   LOGO        Scheme      \     ` ⌒´    /Perl         ひまわり                 /              \        JavaScript                             #$%◎▽▲×・・・      Eiffel                          ALGOL      Python R言語

ややこしいのはライブラリや統合環境 プログラミング言語って覚えるの大変!? 制御文 if, for, while, switch, goto, return, (), {} ... 演算子 +, -, /, *, %, mod, and, or, xor, sizeof ... データ型と変数 int, float, string, struct/class, variant, ... ややこしいのはライブラリや統合環境

変数の種類 グローバル変数 静的変数 動的変数 ローカル変数 関数やメソッドの引数 メンバ変数 _ _ / \ / ─ ─ \       _ _    /      \   /  ─    ─ \    /    (●)  (●) \   |       (__人__)  | PART4で各変数について  /      ∩ノ ⊃  /  説明したんだお。  (  \ / _ノ |  |    .\ “  /__|  |   でも、すっとばすw   \ /___ /  

たとえば、こんな画面があったとしましょう。 実際にどのように使われているかな? たとえば、こんな画面があったとしましょう。 ユーザー名 パスワード ログイン キャンセル ユーザー名とパスワードを入力 ログインボタンが押されたら、 入力情報が正しい文字の組み 合わせになっているか検査 ユーザーが存在し、パスワード が正しいかを検証 どのように実装しますか?

ビューとロジックは、分けるよね? ロジック データアクセス Logic::Logic() { } Logic::Check (...) ユーザー名 パスワード ログイン キャンセル ロジック データアクセス Logic::Logic() { } Logic::Check (...) Logic::Login(...) DAC::DAC() { } DAC::Connect(...) DAC::QueryUser(...) ビュー Form::Form() { } Form::OnLoginClick()

Formのコードイメージ Form::OnLoginClick() { string UserName = Text1->Text; string Password = Text2->Text; bool ret = Logic->Check( UserName, Password ); if( ret == true ) ret = Logic->Login( UserName, Password ); } if( ret == false ) : 編集テキストを内部で取得 ロジックに問い合わせ

Logicのコードイメージ bool Logic::Check( string UserName, string Password ) { return 真偽; } bool Logic::Login( string UserName, string Password ) bool exist = DAL->QueryUser( UserName, Password ); return exist;

DALのコードイメージ DAL::QueryUser( string UserName, string Password ) { string SQL=“SELECT COUNT * from UserTable “ “where (UserName=\‘%s\’)” “and (Password=\’%s\’)”; try SQL.FormatString( UserName, Password ); DataBase->Query( SQL ); if( DataSet->Count >= 1 ) return true; } }catch( ... ){ return false;

【余談】保守性を下げる好き勝手な変数の命名 bool Logic::Login( string sUser, string sPsw ) { bool exist = DAL->QueryUser( sUser, sPsw ); return exist; } アナタ以外の人が見ることを忘れずに node *search(node *lhs, node *rhs); node *search(node *left, node *right); 統一された命名規則であることが重要!

ついでに、UserTableのイメージ フィールド 型 サイズ NULL許容 UserName CHAR 40 × Password 20 :

ビューの設計に戻ると・・・ Text1 という名前にしますか? ユーザー名 パスワード コントロールには、 UserName とか ログイン キャンセル コントロールには、 UserName とか Password という 名前を付けますね。

別の例を考えてみましょう。 こんな画面があったら? ■ × 社員コード 社員名 検索 生年月日 閉じる

画面の設計イメージ ■ × 社員コード 社員名 検索 Code Name 生年月日 Birthday 閉じる

Formのコードイメージ Form::OnSearchClick() { string Code = Code->Text; string Name, Birthday; bool ret = Logic->Check( Code ); if( ret == true ) ret = Logic->GetPerson( Code, &Name, &Birthday ); } Name->Text = Name; Birthday->Text = Birthday; :

Logicのコードイメージ bool Logic::Check( string Code ) { // Codeの妥当性検証 return 真偽; } bool Logic::GetPerson( string Code, string *Name, string *Birthday ) bool exist = DAL->QueryPerson(Code, Name, Birthday ); return exist;

DALのコードイメージ DAL::QueryPerson( string Code, string *Name, string *Birthday ) { string SQL=“SELECT * from PersonTable “ “where (Code=\‘%s\’)”; try SQL.FormatString( Code ); DataBase->Query( SQL ); if( DataSet->Count >= 1 ) *Name = Dataset->GetField(“Name”); *Birthday = Dataset->GetField(“Birthday”); return true; } }catch( ... ){ return false;

ついでに、PersonTableのイメージ フィールド 型 サイズ NULL許容 Code INTEGER 8 × Name CHAR 40 Birthday DateTime

ついでに、帳票設計があるとしたら? 社員名簿 コード 氏名 誕生日 Code Name Birthday

変数の名前って、あちこちで出てきますね。 このように・・・ 変数の名前って、あちこちで出てきますね。 毎回毎回、同じ名前を書かなきゃいけないよね。

めんどくさくないですか? なんとかならないんでしょうか? あたりまえ? 世界中のプログラマが、似たような画面やコードや帳票を 毎日せっせと書いています。 めんどくさくないですか? なんとかならないんでしょうか?

定義と宣言を見てみましょう。 ロジック データアクセス Logic::Logic() { } Logic::Check (...) ユーザー名 パスワード UseName Password ログイン キャンセル ロジック データアクセス Logic::Logic() { } Logic::Check (...) Logic::Login(...) DAC::DAC() { } DAC::Connect(...) DAC::QueryUser(...) Logicとのやりとり ビュー Form::Form() { } Form::OnLoginClick() Form/DALとの橋渡し コントロールとの入出力 フィールド 型 サイズ NULL許容 UserName CHAR 40 × Password 20 :

アプリケーションプログラム変数の宣言要因 画面のコントロール名 データベースフィールド名 帳票ラベル/カラム名

Form/Logic/DAL に設計情報から そこで・・・ Form/Logic/DAL に設計情報から 自動的に変数を作り出してしまおう という試み。

基本クラスでXMLを取り込み自動的に内部変数を用意する Form/Logic/DAL クラスを作る。 <Form Name=“Form1”> <UserInterface> <Field Name=“UserName”, DisplayName=“ユーザー名”, Type=“String”, ... > <Field Name=“Password”, DisplayName=“パスワード”, Type=“String”, ... > </UserInterface> </Form> <Database Name=“AppDB”> <Table Name=“UserTable”> <Field Name=“UserName”, DisplayName=“ユーザー名”, Type=“String”, ... > <Field Name=“Password”, DisplayName=“パスワード”, Type=“String”, ... > </Table> </Database> 基本クラスでXMLを取り込み自動的に内部変数を用意する Form/Logic/DAL クラスを作る。

ちょっとまって。ホントに便利になる? Form::OnSearchClick() { string Code = Code->Text; string Name, Birthday; bool ret = Logic->Check( Code ); if( ret == true ) ret = Logic->GetPerson( Code, &Name, &Birthday ); } Name->Text = Name; Birthday->Text = Birthday; :

基底クラスの Fields[] 変数を利用してみると・・・ Form::OnLoginClick() { bool ret=Logic->Check(Fields[“UserName”], Fields[“Password”]); if( ret == true ) ret = Logic->Login(Fields[“UserName”], Fields[“Password”]); } if( ret == false ) :        ____          /⌒三 ⌒\      /( ○)三(○)\  よけいにめんどくさくなったお   /::::::⌒(__人__)⌒:::::\   |     |r┬-|     |   \      `ー'´   / 

似通った処理をコンポーネントにしてしまおうぜっ!みたいな(笑) PART6 アプリケーション・パターン 似通った処理をコンポーネントにしてしまおうぜっ!みたいな(笑)

コントロールから値を取り出し、ロジックでCheck後にLogin ビューとロジックの内部処理 ロジック ユーザー名 パスワード ログイン キャンセル データアクセス Logic::Check (...) { } Logic::Login(...) Logic::Cancel (...) 文字妥当性 登録されてるの? DAC::QueryUser(...) { } DAC::Connect(...) 登録されてるの? ビュー Form::OnLoginClick() { } Form::OnCancelClick() ログインの記録とか コントロールから値を取り出し、ロジックでCheck後にLogin なにかする 終了処理 ロジックでCancel

Form::OnSearchClick() { } ■ × 社員コード 社員名 検索 生年月日 閉じる ロジック データアクセス Logic::Check (...) { } Logic::Search(...) 文字妥当性 登録されてるの? DAC::QueryUser(...) { } DAC::Search(...) 登録されてるの? ビュー Form::OnSearchClick() { } Form::OnChangeField() 社員コードで データ検索 コントロールから値を取り出し、ロジックでCheck後にSearch 社員検索SQL発行 データセットからフォーム用変数の通知 ロジックから値の変更通知を受け取ったら、コントロールに設定

注意:コードはあくまでもふいんきwです。 これら2つを1つにできないでしょうか? BaseForm::OnActionExecute() { UpdateFields();//おまじない //入力コントロールを列挙 foreach( Control *control = InputControls ){ // ロジックのプロパティに入力値を転送 Logic->Fields[control->Name] = Fields[ control->Name]; } // ロジックに値チェックをお願いする if( Logic->Check() == true ){ Logic->Execute(); 注意:コードはあくまでもふいんきwです。        ____          /⌒三 ⌒\      /( ○)三(○)\  ごちゃまぜに      /::::::⌒(__人__)⌒:::::\ なっちまうお?   |     |r┬-|     |   \      `ー'´   / 

BaseForm::OnPropertyNotifyChanged() { //表示コントロールを列挙 foreach( Control BaseForm::OnPropertyNotifyChanged() { //表示コントロールを列挙 foreach( Control *control = DisplayControls ){ // ロジックのプロパティに入力値を転送 Fields[control->Name] = Logic->Fields[control->Name]; } Repaint(); ■ × 社員コード 社員名 検索 生年月日 閉じる 表示コントロールに 値が設定される

Logicはどうなる? bool BaseLogic::Check() { return true; } bool BaseLogic::Execute() 検証すべきフィールドや条件は毎回異なるので、基底クラス(BaseLogic)では汎用的な実装はできませんね。 何を実行するのか、というのも要件によって異なりますので、基底クラスで実装できにくいですね・・・        ____      /ノ   ヽ、_\     /( ○)}liil{(○)\    (意味なさそうだお)   /    (__人__)   \   |   ヽ |!!il|!|!l| /   |      \    |ェェェェ|     /   /              \

派生クラスで個別対応? class LoginLogic : public BaseLogic … bool LoginLogic::Check() { return DAL->QueryUser(Fields[ “UserName” ], Fields[ “Password” ]); } 仮にロジックを個別実装することになったとしても、この方法が実現できれば、少なくともフォームのコードについては基底クラスが処理してくれるので、画面設計だけやっておけばロジックの必要箇所の実装だけですむことになります。

標準のアクションリスト 一般的な業務アプリケーションの場合、オペレータのアクションの入り口(メニューやボタン)には、次のようなアクションが用意されます。 「キャンセル」 「OK(実行)」「更新」「登録」「確定」 「削除」「検索」 「前ページ」「次ページ」 「コピー」「貼り付け」などなど 定型ロジックを基底クラスにうめこんじゃおう

Formの[OK]処理 入力フィールドを検証(Check) >チェックNGの場合、メッセージ表示 >間違った箇所にカーソル移動 チェックOKなら、実行処理(Execute) >必要な保存処理を実施する

フォームを閉じる。 アプリケーションフォームならプログラムを終了する Formの[キャンセル]処理 フォームを閉じる。 アプリケーションフォームならプログラムを終了する        / ̄ ̄ ̄ \  ホジホジ      / ―   ― \     /   (●)  (●)  \    えー???     |     (__人__)      |   このくらいまでならわかるけど     \   mj |⌒´     /  なかなかそう簡単に共通化は        〈__ノ        できないんじゃなぁい???       ノ   ノ

グリッドを持つ画面 月間一覧表 ■ × 月 Month 商品コード 商品名 顧客コード 数量 単価 金額 ProductId Product 表示 商品コード 商品名 顧客コード 数量 単価 金額 ProductId Product CutomerId Count UnitPrice Amount 赤い文字はXMLで定義された名前 前ページ 次ページ 閉じる

基底データアクセスロジックの一部・・・ [表示]ボタン処理 string SQL = “SELECT “ foreach( field = OutputFields ){ SQL += field->Name; if( field != End of List ){ SQL += “,“; } SQL += “from “ +DatabaseTable; SQL += “WHERE “; foreach( field = InputFields ){ SQL += field->Name + “= \’”      + field->Value + “\’”; SQL += “&&”; SELECT ProductId,Product,CutomerId,Count,UnitPrice,Amount from UserDatabase.UserTable where Month = “5”; ページ行数+1を選択とかもあり。 この辺もXMLで定義

[次ページ]ボタン処理(あくまでもイメージw) BaseLogic::NextPage() { DAL->NextPage( CurrentPage ); foreach( field = Grid[ “グリッドの名前” ].Fields ) field[ フィールド名 ] = DAL->Dataset[ フィールド名 ]; } Observers->Notify( GRID_CHANGE, グリッド名); SQL発行 データセットからローカルに値を取得 グリッドを表示しているフォームに変更通知

そのとおり。 DBとは異なる格納なら、DALだけかえてしまえばいいんじゃない? (設定情報をiniファイルに書いたりレジストリにしたり) データベースがあるとは限らない! そのとおり。 DBとは異なる格納なら、DALだけかえてしまえばいいんじゃない? (設定情報をiniファイルに書いたりレジストリにしたり) データベース、ini ファイル、レジストリの入出力があれば、多くのアプリケーションでは満足なのでは?

通信を利用するアプリケーションに適用できない! そんなことはないっす。 一般的な通信手段として ・TCP/IPとか ・COMポートとか は、標準的なやりとりで吸収できます。

・サーバーアプリケーション ServerSocket ・クライアントアプリケーション ClientSocket サーバアプリとクライアントアプリ ・サーバーアプリケーション ServerSocket ・クライアントアプリケーション ClientSocket          ____        / \  /\ キリッ .     / (ー)  (ー)\         /   ⌒(__人__)⌒ \   基底コンポーネントの     |      |r┬-|    |   考え方、固まったお      \     `ー'´   /     ノ            \   /´               ヽ  |    l              \  ヽ    -一''''''"~~``'ー--、   -一'''''''ー-、.   ヽ ____(⌒)(⌒)⌒) )  (⌒_(⌒)⌒)⌒))

たとえば、どうなる? 典型的な例では、「マスターメンテナンス画面」 テーブル設計 メンテナンス画面 それぞれのXML定義 だけで、コードを書かずにできあがってしまう!      /⌒  ⌒\      ほんとかお?    /( ●)  (●)\   /::::::⌒(__人__)⌒::::: \   よろしくおながいしますお!   |     |r┬-|     |    \      `ー'´     /

アプリケーションの設定情報 画面レイアウト、XML定義だけでコードを書かなくて、できちゃう。 たとえば、どうなる? アプリケーションの設定情報 画面レイアウト、XML定義だけでコードを書かなくて、できちゃう。        ____      /      \    /  _ノ  ヽ、_  \   /  o゚⌒   ⌒゚o  \  めんどくさかったお    |     (__人__)    |   \     ` ⌒´     /

プログラムの開発時間を大幅に短縮できる!      /⌒  ⌒\      ほんとかお?    /( ●)  (●)\   /::::::⌒(__人__)⌒::::: \   定時で帰っていいのかお?   |     |r┬-|     |    \      `ー'´     / デスマーチからの解放!

現在、誠意開発中(笑) ____ /ノ ヽ、_\ /( ○)}liil{(○)\ まだできてないのかお! / (__人__) \        ____      /ノ   ヽ、_\     /( ○)}liil{(○)\    まだできてないのかお!   /    (__人__)   \   |   ヽ |!!il|!|!l| /   |      \    |ェェェェ|     /   /              \

____ / \ / ─ ─\ 残念ながら時間がきてしまったようです。 / ,(●) (●)、\ | (__人__) | \ ` ⌒´ / ,,.....イ.ヽヽ、___ ーーノ゙-、. 次回は、ここで紹介したフレームワークを : | ‘; \_____ ノ.| ヽ I 実際にデモを交えてご紹介しましょう。 | \/゙(__)\,| i | > ヽ. ハ | || いつになるのか、皆目見当もつかないわけだw

ご静聴ありがとうございました。 m(_._)m        ____      /      \    /  _ノ  ヽ、_  \   /  o゚⌒   ⌒゚o  \  また今度だお。   |     (__人__)    |   \     ` ⌒´     /                                  ,.へ   ___                             ム  i  「 ヒ_i〉                            ゝ 〈  ト ノ                           iニ(()  i  {              ____           |  ヽ  i  i           /__,  , ‐-\           i   }  |   i         /(●)   ( ● )\       {、  λ  ト-┤.      /    (__人__)    \    ,ノ  ̄ ,!  i   ゝ、_     |     ´ ̄`       | ,. '´ハ   ,! . ヽ、    `` 、,__\              /" \  ヽ/    \ノ ノ   ハ ̄r/:::r―--―/::7   ノ    /        ヽ.      ヽ::〈; . '::. :' |::/   /   ,. "         `ー 、    \ヽ::. ;:::|/     r'"      / ̄二二二二二二二二二二二二二二二二ヽ      | |       お し ま い         │|      \_二二二二二二二二二二二二二二二二ノ Special thanks for Yaruo charactors