Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9738

C#er、Delphiを学ぶ③(Delphiで依存性の注入やってみる)

$
0
0
はじめに Delphiを始めてちょうど1か月くらい経った。慣れたようで慣れないようで...なわけだが、一番思うのは「WEB上のDelphi関連の記事が少なすぎる」という問題である。とりわけ設計にまつわる記事をほぼほぼ見かけず、これじゃWell Architectなコード書けんやろと思う。そんな中、Delphi沼にちょいと足を踏み込んだ身として何かしら貢献できたらなぁーと思い、修行がてら書こうと思ったわけで。 仕様 はじめての「でるふぁいででぃーあい」といったところで、まずは単純な感じ。DIコンテナは使わず、コンストラクタにインターフェースを注入する、いわゆる「Poor man's DI」での実装。 ファイル(a.txt)から最初の1行を読みとる 読み取った内容を違うファイル(b.txt)に書き込む インターフェースの実装方法について エンバカの公式サイト(docwiki)みたら、インターフェースにGUIDついてた。しかも「TInterfacedObject」なるものも継承してる。なにこれ超怖い、わからない。検索したら、Delphiでのインターフェースの実装方法にまつわる以下の記事が出てきて参考になった。 インターフェース使っててハマりそうなところをつらつらと http://delphimaniacs.blogspot.com/2013/12/delphi-interface.html なるへそ。要は凝ったことしない限りGUIDつけんでもいいが、付けといた方が無難といったところか。ショートカット「Ctrl + Alt + G」でGUIDを追加ヨシッと。Visual Studioと同じキーの割り当て設定してるよね?(タイトル回収) 実装 FileReaderクラス ファイルを読み込む役割を担うクラス。GetContent関数の中で、ファイルの1行目の内容を返してくれる。 FileReader.pas unit FileReader; interface uses System.Classes; type IFileReader = interface ['{FA610526-A7B4-4C44-AB9D-143B50578D48}'] function GetContent(): string; end; TFileReader = class(TInterfacedObject, IFileReader) private FData: TStream; FDataReader: TStreamReader; public constructor Create(AFileName: string); destructor Destroy; override; function GetContent(): string; end; implementation uses System.SysUtils; constructor TFileReader.Create(AFileName: string); begin inherited Create; FData := TFileStream.Create(AFileName, fmOpenRead); FDataReader := TStreamReader.Create(FData); end; destructor TFileReader.Destroy; begin FreeAndNil(FDataReader); FreeAndNil(FData); inherited; end; function TFileReader.GetContent(): string; begin if not FDataReader.EndOfStream then begin Result := FDataReader.ReadLine; end; end; end. FileWriterクラス ファイルへの書き込みの役割を担うクラス。Write関数内で引数で渡された内容をファイルに吐き出す。 FileWriter.pas unit FileWriter; interface uses System.Classes; type IFileWriter = interface ['{7C912111-3757-40DD-94FD-173377F8FE95}'] procedure Write(AContent: string); end; TFileWriter = class(TInterfacedObject, IFileWriter) private FData: TStream; FDataWriter: TStreamWriter; public constructor Create(AFileName: string); destructor Destroy; override; procedure Write(AContent: string); end; implementation uses System.SysUtils; constructor TFileWriter.Create(AFileName: string); begin inherited Create; FData := TFileStream.Create(AFileName, fmCreate); FDataWriter := TStreamWriter.Create(FData); end; destructor TFileWriter.Destroy; begin FreeAndNil(FDataWriter); FreeAndNil(FData); inherited; end; procedure TFileWriter.Write(AContent: string); begin FDataWriter.WriteLine(AContent); end; end. FileService コンストラクタで受け取ったReader,Writerを元に、仕様を実現する役割を担うクラス(命名適当や、すまん )。 FileService.pas unit FileService; interface uses FileWriter, FileReader; type TFileService = class private FFileReader: IFileReader; FFileWriter: IFileWriter; public constructor Create(AFileReader: IFileReader; AFileWriter: IFileWriter); procedure Execute; end; implementation uses System.SysUtils; constructor TFileService.Create(AFileReader: IFileReader; AFileWriter: IFileWriter); begin inherited Create; FFileReader := AFileReader; FFileWriter := AFileWriter; end; procedure TFileService.Execute; var FileContent: string; begin FileContent := FFileReader.GetContent(); FFileWriter.Write(FileContent) end; end. エントリポイント(呼び出し元) Reader,Writerのインスタンスを生成し、コンストラクタに注入する。実装イメージは↓ FileReader := TFileReader.Create('C:\tmp\a.txt'); FileWriter := TFileWriter.Create('C:\tmp\b.txt'); FileService := TFileService.Create(FileReader, FileWriter); FileService.Execute(); さいごに こんな感じでビジネスロジックと永続化層を分離できましたとさ。一緒くたな感じでDelphiでユニットテストも書いてみたいな。メモリリークしてるやもですが許してくださいm(__)m 参考URL DIとかSOLID原則で参考になるなと思った記事 .NETにおけるSOLID設計原則とデザインパターン

Viewing all articles
Browse latest Browse all 9738

Trending Articles