4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2022-01-30

はじめに

Delphiを始めてちょうど1か月くらい経った。慣れたようで慣れないようで...なわけだが、一番思うのは「WEB上のDelphi関連の記事が少なすぎる」という問題である。とりわけ設計にまつわる記事をほぼほぼ見かけず、これじゃWell Architectなコード書けんやろと思う。そんな中、Delphi沼にちょいと足を踏み込んだ身として何かしら貢献できたらなぁーと思い、修行がてら書こうと思ったわけで。

仕様

はじめての「でるふぁいででぃーあい」といったところで、まずは単純な感じ。DIコンテナは使わず、コンストラクタにインターフェースを注入する、いわゆる「Poor man's DI」での実装。

  • ファイル(a.txt)から最初の1行を読みとる
  • 読み取った内容を違うファイル(b.txt)に書き込む

インターフェースの実装方法について

エンバカの公式サイト(docwiki)みたら、インターフェースにGUIDついてた。しかも「TInterfacedObject」なるものも継承してる。なにこれ超怖い、わからない。検索したら、Delphiでのインターフェースの実装方法にまつわる以下の記事が出てきて参考になった。

なるへそ。要は凝ったことしない限り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原則で参考になるなと思った記事

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?