Java基础の教えはどのように正しく依存注入を使いますか?
一、C++の非難
C++が一番非難されているところは、一つのクラスを定義するには二つのファイル、一つはhファイルと一つは.cppファイルを書く必要があります。例えば、CMainFrameクラスを定義し、manframe.hの内容は以下の通りである。
二、Javaの改善
しかし、Javaの出現はこの問題を徹底的に解決しました。一つのクラスは一つに対応しています。javaファイル(その後、他の対象言語に向かってもこの考えを守ってきました。例えば、C啣(氡氡)。
例えばLogService類はログのメンテナンスに用いられます。最初はログの添削機能だけを含んでいます。LogService.javaコードは以下の通りです。
三、誤用による退歩
しかし最近はSpring(Spring Boot、SprigMVC)フレームによるコードを見ていますが、多くの種類のコードがC++の形に戻っています。例えばLogServiceを使う時、開発者はまず一つのinterfaceを定義しました。LogService.javaで:
注意:この設計において、LogService.javaはC++の中に類似しています。hファイル、LogServiceImpl.javaはC++の中に類似しています。cppファイル、この二つのファイルは共通に一つのLogService類を定義しています。このクラスにアップロード方法を追加する必要がある時、LogService.javaとLogServiceImpl.javaは修正されて、またC++の古い道に戻ってきました。これは明らかに向こう側のインターフェースにプログラミングされた曲解である。もしこのようにすべてインターフェースに向かってプログラミングすることができるならば、C++は1つの天然のインターフェースに向かってプログラミングする言語になって、またあれらの複雑な設計のモードを学ぶ必要がありますか?
でも、このようにコードを書くと何か問題がありますか?実はあまり問題がないです。コードが煩雑なだけです。ただ、Java言語を選択したのに、C++のように書かれています。オートマチック車を運転しているのに、マニュアルモードで運転しているようです。
四、インタフェース向けプログラミングを正確に理解する
インタフェース向けプログラミングとは何ですか?ポイントは、インターフェースは変化に基づく抽象的なものです。変わるかもしれないところでこそインターフェースが必要です。上記の例では、ログを書く動作は3つの異なる実装が同時に存在すると仮定する。
1.ログファイルに書き込みます。
2.データベースに書きます。
3.ローカルのログサービスのUDPポートを書きます。
このインターフェースに基づいて3つの異なる実装クラスを書くことができます。
以上で、Java依存注入の文章を正しく使う方法を教えます。これまでの記事を検索したり、次の関連記事を見たりしてください。今後もよろしくお願いします。
C++が一番非難されているところは、一つのクラスを定義するには二つのファイル、一つはhファイルと一つは.cppファイルを書く必要があります。例えば、CMainFrameクラスを定義し、manframe.hの内容は以下の通りである。
class CMainFrame : public CFrameWndEx
{
protected:
CMainFrame();
public:
virtual ~CMainFrame();
};
manframe.cppの内容は以下の通りです。
CMainFrame::CMainFrame()
{
}
CMainFrame::~CMainFrame()
{
}
このクラスに一つの方法を追加する必要があります。hファイルと.cppファイルを同時に修正する必要があります。例えばDefWindowProc関数が追加されます。hファイルに関数を追加する声明が必要です。
class CMainFrame : public CFrameWndEx
{
protected:
CMainFrame();
public:
virtual ~CMainFrame();
protected:
virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
};
manframe.cppにDefWindowProcの定義を追加します。
LRESULT CMainFrame::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if(message==WM_NCPAINT )
{
if(bShow){
ShowWindow(SW_SHOW);
}
else {
ShowWindow(SW_HIDE);
}
}
return CFrameWndEx::DefWindowProc(message, wParam, lParam);
}
C++のクラス定義コードの中で、一回の変化は二つのファイルを修正する必要があり、そのメンテナンスの煩雑さが非難されます。二、Javaの改善
しかし、Javaの出現はこの問題を徹底的に解決しました。一つのクラスは一つに対応しています。javaファイル(その後、他の対象言語に向かってもこの考えを守ってきました。例えば、C啣(氡氡)。
例えばLogService類はログのメンテナンスに用いられます。最初はログの添削機能だけを含んでいます。LogService.javaコードは以下の通りです。
public class LogService{
public ServiceResult<Boolean> addLog (SysLogInfo logInfo) {
......
}
public ServiceResult<Boolean> delLog (String id) {
......
}
}
udateLog方法を追加する必要がある場合は、LogService.javaを修正する必要があります。
public class LogService{
public ServiceResult<Boolean> addLog (SysLogInfo logInfo) {
......
}
public ServiceResult<Boolean> delLog(String id) {
......
}
public ServiceResult<Boolean> updateLog (SysLogInfo logInfo) {
......
}
}
すべてが便利になりました。三、誤用による退歩
しかし最近はSpring(Spring Boot、SprigMVC)フレームによるコードを見ていますが、多くの種類のコードがC++の形に戻っています。例えばLogServiceを使う時、開発者はまず一つのinterfaceを定義しました。LogService.javaで:
public interface LogService {
ServiceResult<Boolean> addLog(SysLogInfo logInfo);
ServiceResult<Boolean> delLog(String id);
}
次に、このインターフェースの実装クラスを定義し、LogServiceImpl.javaにおいて:
public class LogServiceImpl implements LogService{
@Override
public ServiceResult<Boolean> addLog(SysLogInfo logInfo) {
......
}
@Override
public ServiceResult<Boolean> delLog(String id) {
......
}
}
このクラスの実用化が必要なところに@Autowired注解注入を使いました。
public class LogController {
@Autowired
private LogService logservice;
}
開発者がなぜこのようにするのかと聞いて、自信を持って答えました。これはインターフェース向けのプログラミングです。注意:この設計において、LogService.javaはC++の中に類似しています。hファイル、LogServiceImpl.javaはC++の中に類似しています。cppファイル、この二つのファイルは共通に一つのLogService類を定義しています。このクラスにアップロード方法を追加する必要がある時、LogService.javaとLogServiceImpl.javaは修正されて、またC++の古い道に戻ってきました。これは明らかに向こう側のインターフェースにプログラミングされた曲解である。もしこのようにすべてインターフェースに向かってプログラミングすることができるならば、C++は1つの天然のインターフェースに向かってプログラミングする言語になって、またあれらの複雑な設計のモードを学ぶ必要がありますか?
でも、このようにコードを書くと何か問題がありますか?実はあまり問題がないです。コードが煩雑なだけです。ただ、Java言語を選択したのに、C++のように書かれています。オートマチック車を運転しているのに、マニュアルモードで運転しているようです。
四、インタフェース向けプログラミングを正確に理解する
インタフェース向けプログラミングとは何ですか?ポイントは、インターフェースは変化に基づく抽象的なものです。変わるかもしれないところでこそインターフェースが必要です。上記の例では、ログを書く動作は3つの異なる実装が同時に存在すると仮定する。
1.ログファイルに書き込みます。
2.データベースに書きます。
3.ローカルのログサービスのUDPポートを書きます。
このインターフェースに基づいて3つの異なる実装クラスを書くことができます。
public class LogServiceFile implements LogService{
}
public class LogServiceDB implements LogService{
}
public class LogServiceUdp implements LogService{
}
もちろんこの時も下のコードを使っているとエラーが発生します。Autowiredは対応インターフェースの唯一の派生タイプのBeanしか装着できないので、この時は3つの派生クラスが存在します。
public class LogController {
@Autowired
private LogService logservice;
}
次のように改善する必要があります。実際の状況に応じて、対応する派生類のオブジェクトを使用します。
public class LogController {
private LogService logservice;
void writeLog(SysLogInfo logInfo){
logservice = GetLogServiceInst();
logservice.addLog(logInfo);
}
}
もしあなたのインターフェースが一つのインプリメンテーションクラスしかないならば、また会える将来に他の実現クラスもないです。それではやはり簡単にして、基本的なクラス定義方式を採用して、コードの複雑さを減らすことをお勧めします。以上で、Java依存注入の文章を正しく使う方法を教えます。これまでの記事を検索したり、次の関連記事を見たりしてください。今後もよろしくお願いします。