入力系(キーボード)まわりの実装を、オブジェクト指向だけで考えてみました。
(C++の言語仕様に関わる部分は、詳しくないのであまり考えられておりません…)
デバイスがシングルトン的な実装を必要としている(2つ取ると一方が無効になるとか)のであれば、
シングルトンがよいと思います。
1:想定されるキーボードの操作を、インターフェースとして定義する(IKeyborad)。
2:IKeyboardを生成するファクトリのインターフェースを定義する(IKeyboardFactory)。
3:実ハードウェアのキーボード入力を扱うクラスを、
IKeyboardの実装として作成する(KeyboardByHuman)。
4:KeyboardByHumanをシングルトンで生成するファクトリを、
IKeyboardFactoryの実装として作成する(KeyboardByHumanFactory)。
ここでKeyboardByHumanをKeyboardByHumanFactoryのprivateな内部クラスとすると、
KeyboardByHumanの生成を制限できる(と思います)。
(この場合、KeyboardByHumanのテストには工夫が必要かもしれません)
↑↑↑ここまで実装↑↑↑
↓↓↓ここから使用↓↓↓
5:キーボードの入力を必要とするクラス(例えば、シューティングゲームでの飛行機)
のコンストラクタの引数(もしくはセッター)に、IKeyboardFactoryを指定する。
6:飛行機のクラスの内部でIKeyboardFactory.createKeyboardでIKeyboardを取得し、
キーボードの入力に従い飛行機を動かす。
7:飛行機クラスのテスト時には、テスト用のIKeyboradを実装したクラスと、
そのクラスを返すIKeyboardFactoryを実装したクラスを渡してテストする。
8:飛行機クラスの生成も飛行機ファクトリで行い、
例えば、デフォルトでKeyboardByHumanFactoryを渡すように作成する。
IKeyboardFactoryにこだわる理由は…
1、IKeyboardインターフェースでは、インスタンスを取得する(staticな)メソッドを定義できないから。
2、そもそもIKeyboardはキーボード(の操作)を表したもので、生成とは関係がないから。
3、コンストラクタに引数が多かったり生成時のお約束が面倒でも、ファクトリだけが行えばよいから。
4、KeyboardByHumanの生成破棄が自由に行えるようになり、テストも行いやすくなるから。
IKeyboardにこだわる理由は…
1、飛行機クラスのテストと操縦方法やデバイスの変更が容易になるから。
十字キーを表現しただけのIKeyboardなら、例えばゲームパッドに切り替えることもできます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。