functionによる設計の改善
1525 ワード
このような適用シーンには,AとBの2つのクラスがあり,BではAを呼び出す1つのメソッド(メンバ関数)が必要であると仮定する.では、私たちのコードはこのようなものかもしれません.
呼び出しコードは次のとおりです.
上のコードを見て、何か問題があるか見てみましょう.の2つのクラスの中でBはAに依存関係を生んで、これは少し不快です; いつか私たちがAの代わりに別のクラスCを使いたいと思っているのは、Bを書き直すことを意味しています.これはもっと不快です.
上記の2つの問題は実質的に結合の問題であり,依存関係は強い結合であり,結合度が高くなるとコード可読性とメンテナンス性が悪くなる.
この2つのクラスの関係を解析し,BでAのメンバー関数を呼び出して依存を生じた.この呼び出しは完全に関数ポインタを使用することができ、C++の関数ポインタを使用するのは面倒なのでfunctionで代用します.改良されたBの定義は以下の通りである.
呼び出し方法は以前とあまり差がなく、割り当て操作のオブジェクトをAのポインタからAのメンバー関数に変更しただけです.
コードは少し複雑に見えますが、コードロジックの観点から多くの改善があります. BとAは完全にデカップリングされ、実行期間にBのオブジェクトのみがAのオブジェクトに依存し、この依存は呼び出し者の制御下に完全にある. AをCに置き換えたいなら、交換して、呼び出しコードを変更すればいいです.Bの定義コードは1行も動かない--これは私たちが追求している柔軟性と拡張性です.
C++0 xの新しい特性としてstd::functionとstd::bindは現在VS 2010でのみサポートされており、他のコンパイラの学生はboostライブラリを代替案として使用することができ、使い方はまったく同じである.
class A
{
public:
void Func(void)
{
printf("%s\r
", __FUNCTION__);
}
};
class B
{
public:
void UseA()
{
a->Func();
}
public:
A* a;
};
呼び出しコードは次のとおりです.
A a;
B b;
b.a = &a;
b.UseA();
上のコードを見て、何か問題があるか見てみましょう.
上記の2つの問題は実質的に結合の問題であり,依存関係は強い結合であり,結合度が高くなるとコード可読性とメンテナンス性が悪くなる.
この2つのクラスの関係を解析し,BでAのメンバー関数を呼び出して依存を生じた.この呼び出しは完全に関数ポインタを使用することができ、C++の関数ポインタを使用するのは面倒なのでfunctionで代用します.改良されたBの定義は以下の通りである.
class B
{
public:
std::function<void(void)> AFunc;
void UseA(void)
{
if(AFunc != NULL) AFunc();
}
};
呼び出し方法は以前とあまり差がなく、割り当て操作のオブジェクトをAのポインタからAのメンバー関数に変更しただけです.
A a;
B b;
b.AFunc = std::bind(&A::Func, &a);
b.UseA();
コードは少し複雑に見えますが、コードロジックの観点から多くの改善があります.
C c;
b.AFunc = std::bind(&C::Func, &c);
b.UseA();
C++0 xの新しい特性としてstd::functionとstd::bindは現在VS 2010でのみサポートされており、他のコンパイラの学生はboostライブラリを代替案として使用することができ、使い方はまったく同じである.