【新規プロジェクト開発環境】
はじめに
新規プロジェクトで開発を行う場合は、ある程度のソケット通信の知識が必要になりますのであらかじめご了承ください。
また▶アーキテクチャのページをご覧になった上で進めていただいた方が用語の理解も含めてより効率的に進められます。
ここではデモ版のソースを例に挙げながら
デモ版のソースを参考にしつつ、ある程度処理の流れを掴んでから進めていくのがスムーズかと思います。
また▶アーキテクチャのページをご覧になった上で進めていただいた方が用語の理解も含めてより効率的に進められます。
ここではデモ版のソースを例に挙げながら
php worker
コマンドを使って新規のクラスを作っていきます。デモ版のソースを参考にしつつ、ある程度処理の流れを掴んでから進めていくのがスムーズかと思います。
インストール
以下のコマンドでインストールできます。
※GitHubから直接ダウンロードする場合は>> こちらからどうぞ。
新規プロジェクト開発環境のインストール
インストールが完了すると以下のディレクトリ構成になります。
プロジェクトの構成
Usage表示
それでは動作確認のため、以下のコマンドを実行してメイン処理クラスを作成します。
今回は
以下のように表示されれば成功です。
MainForTestクラス作成
再度
Usage表示
アプリ名
まずは以下のコマンドを実行して今回作成したサーバーを起動した状態にしてください。
サーバー起動
その後PowerShellなどで以下のように
Listenポート確認
以降の説明ではデモの中で一番オーソドックスなWebsocket版チャットサーバーを例に取り上げて話を進めます。
※GitHubから直接ダウンロードする場合は>> こちらからどうぞ。
新規プロジェクト開発環境のインストール
> composer create-project socket-manager/new-project <インストール先のディレクトリ名>
インストールが完了すると以下のディレクトリ構成になります。
プロジェクトの構成
/app /InitClass 初期化クラス /UnitParameter UNITパラメータクラス /ProtocolUnits プロトコルUNIT定義クラス /CommandUnits コマンドUNIT定義クラス /MainClass メイン処理クラス /logs ログ出力用 /setting 設定ファイル用
php worker
コマンドを実行すると以下のようなUsageが表示されます。Usage表示
> php worker SOCKET-MANAGER Framework 1.0.0 Usage: command [arguments] main Empty... craft craft:init <初期化クラス名> 初期化クラスの生成 craft:parameter <UNITパラメータクラス名> UNITパラメータクラスの生成 craft:protocol <プロトコルUNIT定義のクラス名> プロトコルUNIT定義のクラスとステータス名Enumの生成 craft:command <コマンドUNIT定義のクラス名> コマンドUNIT定義のクラスとキュー/ステータス名Enumの生成 craft:main <メイン処理のクラス名> メイン処理クラスの生成 craft:setting <設定ファイル名> 設定ファイルの生成 craft:locale <メッセージファイル名> メッセージファイルの生成※
laravel:command
コマンドに関してはLaravel環境でしか表示されません。それでは動作確認のため、以下のコマンドを実行してメイン処理クラスを作成します。
今回は
MainForTest
という名前で作成します。以下のように表示されれば成功です。
MainForTestクラス作成
> php worker craft:main MainForTest [success] メイン処理クラスの生成に成功しました (MainForTest)
再度
php worker
を実行してみます。Usage表示
> php worker SOCKET-MANAGER Framework 1.0.0 Usage: command [arguments] main app:main-for-test Command description craft craft:init <初期化クラス名> 初期化クラスの生成 craft:parameter <UNITパラメータクラス名> UNITパラメータクラスの生成 craft:protocol <プロトコルUNIT定義のクラス名> プロトコルUNIT定義のクラスとステータス名Enumの生成 craft:command <コマンドUNIT定義のクラス名> コマンドUNIT定義のクラスとキュー/ステータス名Enumの生成 craft:main <メイン処理のクラス名> メイン処理クラスの生成 craft:setting <設定ファイル名> 設定ファイルの生成 craft:locale <メッセージファイル名> メッセージファイルの生成
アプリ名
main-for-test
という名前で登録されている事が確認できます。まずは以下のコマンドを実行して今回作成したサーバーを起動した状態にしてください。
サーバー起動
> php worker app:main-for-test 10000
その後PowerShellなどで以下のように
netstat
コマンドを実行して10000ポートがListenされている事が確認できれば正常にインストールされています。Listenポート確認
> netstat -ano | Select-String -Pattern "127.0.0.1:10000" TCP 127.0.0.1:10000 0.0.0.0:0 LISTENING 21536
以降の説明ではデモの中で一番オーソドックスなWebsocket版チャットサーバーを例に取り上げて話を進めます。
初期化クラスの実装
初期化クラスのソースは以下のコマンドで作成できます。
初期化クラスの作成
それでは以下のWebsocket版チャットサーバーのソースをご覧ください。
app/InitClass/InitForWebsocket.php
ここで必須になる実装は大きく分けると以下の7点になります。
各々のメソッドはnullを返す事で無効化できます。
InitForTest
という名前で作成する場合、以下のように表示されれば成功です。初期化クラスの作成
> php worker craft:init InitForTest [success] 初期化クラスの生成に成功しました (InitForTest)生成されるファイル
/app /InitClass InitForTest.php
それでは以下のWebsocket版チャットサーバーのソースをご覧ください。
app/InitClass/InitForWebsocket.php
class InitForWebsocket implements IInitSocketManager { . . . /** * ログライターの取得 * * nullを返す場合は無効化(但し、ライブラリ内部で出力されているエラーメッセージも出力されない) * * @return mixed "function(string $p_level, array $p_param): void" or null(ログ出力なし) */ public function getLogWriter() { return function(string $p_level, array $p_param) { . . . }; } /** * シリアライザーの取得 * * nullを返す場合は無効化となる。 * エラー発生時はUnitExceptionクラスで例外をスローして切断する。 * * @return mixed "function(mixed $p_data): mixed" or null(変更なし) */ public function getSerializer() { return function($p_data) { . . . }; } /** * アンシリアライザーの取得 * * nullを返す場合は無効化となる。 * エラー発生時はUnitExceptionクラスで例外をスローして切断する。 * * @return mixed "function(mixed $p_data): mixed" or null(変更なし) */ public function getUnserializer() { return function($p_data) { . . . }; } /** * コマンドディスパッチャーの取得 * * 受信データからコマンドを解析して返す * * コマンドUNIT実行中に受信データが溜まっていた場合でもコマンドUNITの処理が完了するまで * 待ってから起動されるため処理競合の調停役を兼ねる * * nullを返す場合は無効化となる。エラー発生時はUnitExceptionクラスで例外をスローして切断する。 * * @return mixed "function(SocketManagerParameter $p_param, mixed $p_dat): ?string" or null(変更なし) */ public function getCommandDispatcher() { return function(ParameterForWebsocket $p_param, $p_dat): ?string { . . . }; } /** * 緊急停止時のコールバックの取得 * * 例外等の緊急切断時に実行される。nullを返す場合は無効化となる。 * * @return mixed "function(SocketManagerParameter $p_param)" */ public function getEmergencyCallback() { return function(ParameterForWebsocket $p_param) { . . . }; } /** * UNITパラメータインスタンスの取得 * * nullの場合はSocketManagerParameterのインスタンスが適用される * * @return ?SocketManagerParameter SocketManagerParameterクラスのインスタンス(※1) * @see:RETURN (※1)当該クラス、あるいは当該クラスを継承したクラスも指定可 */ public function getUnitParameter(): ?SocketManagerParameter { . . . } }
ここで必須になる実装は大きく分けると以下の7点になります。
各々のメソッドはnullを返す事で無効化できます。
- ■IInitSocketManagerのインプリメント
- ライブラリが以下に記載のハンドラーの取り込み時に利用する。
- ■getLogWriterメソッドの実装
-
ライブラリ内でのログ出力に利用。
ハンドラーにする事でerror_log
関数やフレームワークのLogger
等の利用が可能。 - ■getSerializerメソッドの実装
-
送受信スタック内ペイロードデータのシリアライズ時に利用する。
今回のデモではJSONエンコード時に利用。 - ■getUnserializerメソッドの実装
-
送受信スタック内ペイロードデータのアンシリアライズ時に利用する。
今回のデモではJSONデコード時に利用。 - ■getCommandDispatcherメソッドの実装
- クライアントから受信したペイロード部を解析して対応するコマンドキュー名を返す。
- ■getEmergencyCallbackメソッドの実装
- 相手先による切断・コマンドディスパッチャーでの例外発生・アライブチェックタイムアウトなどの緊急停止時にコールされる。
- ■getUnitParameterメソッドの実装
- UNITパラメータとして利用される。グローバルエリアの管理が必要ないのであれば
SocketManagerParameter
クラスをそのまま使っても構わない。
プロトコル部の実装
プロトコル部のソースは以下のコマンドで作成できます。
プロトコル部の生成
この部分の実装は主にソケットプロトコルに関係する送受信の処理を行うところで、実際の通信処理はこのプロトコル部で行います。
それでは以下のWebsocket版チャットサーバーのソースをご覧ください。
Websocket版チャットサーバーのソース:app/ProtocolUnits/ProtocolForWebsocket.php
ここで必須になる実装は大きく分けると以下の4点になります。
※プロトコル部で利用するキュー名は全てライブラリ側の
プロトコル部の予約済Enum定義:ProtocolQueueEnum.php
必ずしも全てのキュー名を使用する必要はありませんがサーバーサイドのWebsocketの規約では
ProtocolForTest
という名前で作成する場合、以下のように表示されれば成功です。プロトコル部の生成
> php worker craft:protocol ProtocolForTest [success] プロトコルUNITクラスの生成に成功しました (ProtocolForTest) [success] プロトコルUNITのキュー名Enumの生成に成功しました (ProtocolForTestQueueEnum) [success] プロトコルUNITのステータス名Enumの生成に成功しました (ProtocolForTestStatusEnum)生成されるファイル
/app /ProtocolUnits ProtocolForTest.php ProtocolForTestQueueEnum.php ProtocolForTestStatusEnum.php
この部分の実装は主にソケットプロトコルに関係する送受信の処理を行うところで、実際の通信処理はこのプロトコル部で行います。
それでは以下のWebsocket版チャットサーバーのソースをご覧ください。
Websocket版チャットサーバーのソース:app/ProtocolUnits/ProtocolForWebsocket.php
class ProtocolForWebsocket implements IEntryUnits { // キューリスト protected const QUEUE_LIST = [ ProtocolQueueEnum::ACCEPT->value, // アクセプトを処理するキュー ProtocolQueueEnum::RECV->value, // 受信処理のキュー ProtocolQueueEnum::SEND->value, // 送信処理のキュー ProtocolQueueEnum::CLOSE->value, // 切断処理のキュー ProtocolQueueEnum::ALIVE->value // アライブチェック処理のキュー ]; /** * キューリストの取得 * * @return array キュー名のリスト */ public function getQueueList(): array { return self::QUEUE_LIST; } /** * ステータスUNITリストの取得 * * @param string $p_que キュー名 * @return array キュー名に対応するUNITリスト */ public function getUnitList(string $p_que): array { $ret = []; if($p_que === ProtocolQueueEnum::ACCEPT->value) { $ret[] = [ 'status' => ProtocolStatusEnumForWebsocket::START->value, 'unit' => $this->getAcceptStart() ]; $ret[] = [ 'status' => ProtocolStatusEnumForWebsocket::CREATE->value, 'unit' => $this->getAcceptCreate() ]; $ret[] = [ 'status' => ProtocolStatusEnumForWebsocket::SEND->value, 'unit' => $this->getAcceptSend() ]; } . . . return $ret; } . . . /** * ステータス名: START * * 処理名:受信 * * @param ParameterForWebsocket $p_param UNITパラメータ * @return ?string 遷移先のステータス名 */ protected function getAcceptStart() { return function(ParameterForWebsocket $p_param): ?string { . . . }; } . . . }
ここで必須になる実装は大きく分けると以下の4点になります。
- ■IEntryUnitsのインプリメント
- ライブラリがプロトコル部の取り込み時に利用する
- ■getQueueListメソッドの実装
- プロトコル部で利用するキューのリストを返す
- ■getUnitListメソッドの実装
- 引数のキュー名に対応するUNITのリストを返す
- ■各UNITの実装
getUnitList
メソッドで返している定義済みのUNIT処理を実装
getAcceptStart
メソッドでクロージャとして返していますが、グローバル関数名を指定する事も可能です。※プロトコル部で利用するキュー名は全てライブラリ側の
ProtocolQueueEnum
クラスで予約されています。プロトコル部の予約済Enum定義:ProtocolQueueEnum.php
enum ProtocolQueueEnum: string { /** * @var アクセプト時のキュー名 */ case ACCEPT = 'accept'; /** * @var コネクション時のキュー名 */ case CONNECT = 'connect'; /** * @var 受信時のキュー名 */ case RECV = 'recv'; /** * @var 送信時のキュー名 */ case SEND = 'send'; /** * @var 切断時のキュー名 */ case CLOSE = 'close'; /** * @var アライブチェック時のキュー名 */ case ALIVE = 'alive'; }
必ずしも全てのキュー名を使用する必要はありませんがサーバーサイドのWebsocketの規約では
CONNECT
を除いて全てルール化されています。
コマンド部の実装
コマンド部のソースは以下のコマンドで作成できます。
コマンド部の生成
プロトコル部が通信を担う部分であるのに対して、コマンド部ではクライアント側とコマンド単位でのデータのやり取りを行って、コマンドの解釈とその内容に応じたレスポンスを返す部分になります。
まずは以下のWebsocket版チャットサーバーのソースをご覧ください。
Websocket版チャットサーバーのソース:app/CommandUnits/CommandForWebsocket.php
構成内容はプロトコル部とほぼ同じで、必須になる実装も大きく分けると以下の4点になります。
※コマンド部で利用するキュー名は自由定義です。特に予約されているものもありません。
CommandForTest
という名前で作成する場合、以下のように表示されれば成功です。コマンド部の生成
> php worker craft:command CommandForTest [success] コマンドUNITクラスの生成に成功しました (CommandForTest) [success] コマンドUNITのキュー名Enumの生成に成功しました (CommandForTestQueueEnum) [success] コマンドUNITのステータス名Enumの生成に成功しました (CommandForTestStatusEnum)生成されるファイル
/app /CommandUnits CommandForTest.php CommandForTestQueueEnum.php CommandForTestStatusEnum.php
プロトコル部が通信を担う部分であるのに対して、コマンド部ではクライアント側とコマンド単位でのデータのやり取りを行って、コマンドの解釈とその内容に応じたレスポンスを返す部分になります。
まずは以下のWebsocket版チャットサーバーのソースをご覧ください。
Websocket版チャットサーバーのソース:app/CommandUnits/CommandForWebsocket.php
/** * コマンドUNIT登録クラス * * IEntryUnitsインタフェースをインプリメントする */ class CommandForWebsocket implements IEntryUnits { // キューリスト protected const QUEUE_LIST = [ CommandQueueEnumForWebsocket::ENTRANCE->value, // entranceコマンドを処理するキュー CommandQueueEnumForWebsocket::MESSAGE->value, // messageコマンドを処理するキュー CommandQueueEnumForWebsocket::EXIT->value, // exitコマンドを処理するキュー CommandQueueEnumForWebsocket::CLOSE->value, // closeコマンドを処理するキュー CommandQueueEnumForWebsocket::PRIVATE->value, // privateコマンドを処理するキュー CommandQueueEnumForWebsocket::PRIVATE_RESULT->value, // private-resultコマンドを処理するキュー CommandQueueEnumForWebsocket::USERSEARCH_RESULT->value // usersearch-resultコマンドを処理するキュー ]; /** * キューリストの取得 * * @return array キュー名のリスト */ public function getQueueList(): array { return static::QUEUE_LIST; } /** * ステータスUNITリストの取得 * * @param string $p_que キュー名 * @return array キュー名に対応するUNITリスト */ public function getUnitList(string $p_que): array { $ret = []; if($p_que === CommandQueueEnumForWebsocket::ENTRANCE->value) { $ret[] = [ 'status' => CommandStatusEnumForWebsocket::START->value, 'unit' => $this->getEntranceStart() ]; } . . . } . . . /** * ステータス名: START * * 処理名:入室処理開始 * * @param ParameterForWebsocket $p_param UNITパラメータ * @return ?string 遷移先のステータス名 */ protected function getEntranceStart() { return function(ParameterForWebsocket $p_param): ?string { . . . } } . . . }
構成内容はプロトコル部とほぼ同じで、必須になる実装も大きく分けると以下の4点になります。
- ■IEntryUnitsのインプリメント
- ライブラリがコマンド部の取り込み時に利用する
- ■getQueueListメソッドの実装
- コマンド部で利用するキューのリストを返す
- ■getUnitListメソッドの実装
- 引数のキュー名に対応するUNITのリストを返す
- ■各UNITの実装
getUnitList
メソッドで返している定義済みのUNIT処理を実装
getEntranceStart
メソッドでクロージャとして返していますが、グローバル関数名を指定する事も可能です。※コマンド部で利用するキュー名は自由定義です。特に予約されているものもありません。
予約済ステータス
予約されているものは以下ライブラリ側のEnum定義のみです。
予約済Enum定義:StatusEnum.php
プロトコル/コマンド部共通で利用するSTART(処理開始)のみになります。
予約済Enum定義:StatusEnum.php
enum StatusEnum: string { /** * @var UNITの処理開始時のステータス名 */ case START = 'start'; }
プロトコル/コマンド部共通で利用するSTART(処理開始)のみになります。
UNITパラメータの実装
UNITパラメータクラスのソースは以下のコマンドで作成できます。
UNITパラメータクラスの作成
ここで述べているUNITパラメータというのはプロトコル部やコマンド部で定義されているUNITの引数の部分です。
上記のプロトコル部やコマンド部の例でいえば
この引数には
グローバルエリアを使う必要がなければ特に実装する事は何もありませんが、新規で作成した場合は以下のようにUNIT処理の引数の部分を必要に応じて置き替えてください。
修正前:黄色部分(プロトコル部のデフォルト)
ParameterForTest
という名前で作成する場合、以下のように表示されれば成功です。UNITパラメータクラスの作成
> php worker craft:parameter ParameterForTest [success] UNITパラメータクラスの生成に成功しました (ParameterForTest)生成されるファイル
/app /UnitParameter ParameterForTest.php
ここで述べているUNITパラメータというのはプロトコル部やコマンド部で定義されているUNITの引数の部分です。
上記のプロトコル部やコマンド部の例でいえば
ParameterForWebsocket $p_param
の部分になります。この引数には
SocketManagerParameter
クラスを継承しているものであれば何を指定しても構いません。グローバルエリアを使う必要がなければ特に実装する事は何もありませんが、新規で作成した場合は以下のようにUNIT処理の引数の部分を必要に応じて置き替えてください。
修正前:黄色部分(プロトコル部のデフォルト)
protected function getAcceptStart() { return function(SocketManagerParameter $p_param): ?string { $p_param->logWriter('debug', ['ACCEPT' => 'START']); return null; }; }修正後:赤色部分(新規で作成したクラス)
protected function getAcceptStart() { return function(ParameterForTest $p_param): ?string { $p_param->logWriter('debug', ['ACCEPT' => 'START']); return null; }; }
メイン処理クラスの実装
メイン処理クラスのソースは以下のコマンドで作成できます。
メイン処理クラスの作成
作成されたソースは次の通り。
app/MainClass/MainForTest.php
ここで必須になる実装は初期設定ブロックである以下の3点になります。
MainForTest
という名前で作成する場合、以下のように表示されれば成功です。メイン処理クラスの作成
> php worker craft:main MainForTest [success] メイン処理クラスの生成に成功しました (MainForTest)生成されるファイル
/app /MainClass MainForTest.php
作成されたソースは次の通り。
app/MainClass/MainForTest.php
class MainForTest extends Console { /** * @var string $identifer サーバー識別子 */ protected string $identifer = 'app:main-for-test {port_no?}'; /** * @var string $description コマンド説明 */ protected string $description = 'Command description'; /** * サーバー起動 * */ public function exec() { // 引数の取得 $port_no = $this->getParameter('port_no'); // ソケットマネージャーのインスタンス設定 $manager = new SocketManager('localhost', $port_no); /*********************************************************************** * ソケットマネージャーの初期設定 * * プロトコル/コマンド部等で実装したクラスのインスタンスをここで設定します **********************************************************************/ /** * 初期化クラスの設定 * * $manager->setInitSocketManager()メソッドで初期化クラスを設定します */ /** * プロトコルUNITの設定 * * $manager->setProtocolUnits()メソッドでプロトコルUNITクラスを設定します */ /** * コマンドUNITの設定 * * $manager->setCommandUnits()メソッドでコマンドUNITクラスを設定します */ /*********************************************************************** * ソケットマネージャーの実行 * * ポートの待ち受け処理や周期ドリブン処理を実行します **********************************************************************/ // リッスンポートで待ち受ける $ret = $manager->listen(); if($ret === false) { goto finish; // リッスン失敗 } // ノンブロッキングループ while(true) { // 周期ドリブン $ret = $manager->cycleDriven(); if($ret === false) { goto finish; } } finish: // 全接続クローズ $manager->shutdownAll(); } }
ここで必須になる実装は初期設定ブロックである以下の3点になります。
- ■初期化クラスの設定
- 初期化クラスのインスタンスを生成し、
SocketManager
クラスのsetInitSocketManager
メソッドにインスタンスを引き渡す - ■プロトコルUNITの設定
- プロトコルUNITクラスのインスタンスを生成し、
SocketManager
クラスのsetProtocolUnits
メソッドにインスタンスを引き渡す - ■コマンドUNITの設定
- コマンドUNITクラスのインスタンスを生成し、
SocketManager
クラスのsetCommandUnits
メソッドにインスタンスを引き渡す
設定ファイルの作成
設定ファイルは以下のコマンドで作成できます。
設定ファイルの作成
作成されたソースは次の通り、空の配列のリターン値になります。
setting/test.php
ここでは
設定ファイルで以下のように連想配列を定義していたとします。
setting/test.php
あとはプログラムの方で
configヘルパー関数で値を取得
変数
関数の第一引数にはファイル名を含めたキー名をピリオド区切りで指定します。第二引数には値が取得できなかった場合のデフォルト値を指定します。
test
という名前で作成する場合、以下のように表示されれば成功です。設定ファイルの作成
> php worker craft:setting test [success] 設定ファイルの生成に成功しました (test)生成されるファイル
/setting test.php
作成されたソースは次の通り、空の配列のリターン値になります。
setting/test.php
return [ ];
使い方
設定ファイル内の設定値を取得するヘルパー関数はLaravelと同様に使えるようにしています。ここでは
test_key
という名前の設定名を使って値を取得する場合を例に挙げます。設定ファイルで以下のように連想配列を定義していたとします。
setting/test.php
return [ 'test_key' => 100 ];
あとはプログラムの方で
config
ヘルパー関数を使って以下のように取得するだけです。configヘルパー関数で値を取得
$value = config('test.test_key', null);
変数
$value
には100を返します。関数の第一引数にはファイル名を含めたキー名をピリオド区切りで指定します。第二引数には値が取得できなかった場合のデフォルト値を指定します。
メッセージファイルの作成
メッセージ管理のコマンドは
例えば
メッセージファイルの作成
作成されたソースは次の通り、空の配列のリターン値になります。
locale/ja/test.php
ここでは
メッセージファイルで以下のように連想配列を定義していたとします。
locale/ja/test.php
あとはプログラムの方で
__ヘルパー関数でメッセージを取得
変数
また、以下のようにプレースホルダも使えます。
locale/ja/test.php
変数
setting/app.php
内のlocale
設定項目と連動します。例えば
locale
の項目がja
の場合の挙動は以下の通りです。メッセージファイルの作成
> php worker craft:locale test [success] メッセージファイルの生成に成功しました (test)生成されるファイル
/locale /ja test.php
test.php
のファイルはja
のサブディレクトリに格納されます。作成されたソースは次の通り、空の配列のリターン値になります。
locale/ja/test.php
return [ ];
使い方
メッセージファイル内のメッセージを取得するヘルパー関数はLaravelと同様に使えるようにしています。ここでは
test_key
という名前の設定名を使って値を取得する場合を例に挙げます。メッセージファイルで以下のように連想配列を定義していたとします。
locale/ja/test.php
return [ 'test_key' => 'テストメッセージ' ];
あとはプログラムの方で
__
ヘルパー関数を使って以下のように取得するだけです。__ヘルパー関数でメッセージを取得
$value = __('test.test_key');
変数
$value
には「テストメッセージ」という文字列を返します。また、以下のようにプレースホルダも使えます。
locale/ja/test.php
return [ 'test_key' => '私の名前は:nameです。年齢は:age歳です。' ];プレースホルダを使ってメッセージを取得
$value = __('test.test_key', ['name' => '山田太郎', 'age' => 20]);
変数
$value
には「私の名前は山田太郎です。年齢は20歳です。」という文字列を返します。
おわりに
動作確認をしながら進めるのであれば以下の順に進めるのが効率的かと思います。
そしてプロトコル部とコマンド部のクラスは初期状態のままでいいのでメイン処理クラスで設定だけ済ませておいた上でプロトコル部、あるいはコマンド部のUNITを作成するたびに動作確認していくのが順当かと思います。
UNITパラメータクラスの方はUNIT処理の作成中にグローバルエリアの管理が必要になった時に実装を進める形でよいかと思います。
- 1.初期化クラスの実装
- 2.メイン処理クラスの実装
- 3.プロトコル部の実装
- 4.コマンド部の実装
そしてプロトコル部とコマンド部のクラスは初期状態のままでいいのでメイン処理クラスで設定だけ済ませておいた上でプロトコル部、あるいはコマンド部のUNITを作成するたびに動作確認していくのが順当かと思います。
UNITパラメータクラスの方はUNIT処理の作成中にグローバルエリアの管理が必要になった時に実装を進める形でよいかと思います。