Earn More by Sharing What You Love
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

Tim Corey
35分50秒
デザインパターンは、一般的なソフトウェア開発の問題に対する再利用可能なソリューションであり、より効率的で保守性の高い方法でオブジェクト指向コードを構造化し、実装するためのテンプレートを提供します。 これらのツールは、開発者が柔軟でスケーラブルな方法でオブジェクトの作成、構造、および通信に関する問題を解決するのに役立ちます。 デザインパターンは、より良いコードを書くために開発者を導くベストプラクティスの概念として機能します。 ソフトウェア設計における基本原則の1つに、SOLID原則の一部である単一責任原則(SRP)があります。
彼のビデオ"Design Patterns: Single Responsibility Principle Explained Practically in C# (The S in SOLID)"では、ティム・コーリーが**単一責任原則(SRP)**を探求し、ソフトウェア設計におけるその重要性を強調するとともに、それを効果的に実装する方法について実践的な洞察を提供しています。 この記事では、彼のビデオからの重要な要点の簡潔な概要を提供し、クリーンで保守可能なコードを作成するSRPの重要性を強調する。
ソフトウェア設計において、SOLIDの原則は、保守可能でスケーラブルなコードを作成するために非常に重要です。 また、コードを理解しやすく、テストしやすく、変更しやすくします。 5つの原則-単一責任原則(SRP)、オープン/クローズド原則(OCP)、リスコフ置換原則(LSP)、インターフェース分離原則(ISP)、依存関係逆転原則(DIP)-は、オブジェクト指向設計に不可欠であり、ソリューションをより堅牢にするためにデザインパターンの中で適用することができます。
C#のデザインパターンを適用することで、開発者は一般的な問題をより効果的に解決することができます。 オブジェクトの作成であれ、ツリー構造の定義であれ、シングルインスタンスによる再利用性の確保であれ、デザインパターンはソフトウェアアーキテクチャを強化する定義済みのソリューションを提供します。 ファクトリーメソッド、ビルダー、シングルトンなどのパターンは、柔軟で再利用可能なソリューションを提供し、動作パターンや構造パターンは、複雑さを管理し、システム内のコミュニケーションを改善するのに役立ちます。 これらのパターンを学び活用することで、開発者は保守や拡張が容易なシステムを構築することができます。
TimはSRPの概念について説明し、開発者がコードをベストプラクティスに準拠させることが極めて重要であることを強調します。 SRPでは、クラスは1つの責任または変更理由のみを持つべきであると述べています。 この原則は、クリーンで保守性が高く、スケーラブルなコードを維持するのに役立ちます。
TimはC#で簡単なコンソールアプリケーションをセットアップし、ユーザーの姓名を尋ね、これらの名前を検証し、ユーザー名を生成する。 最初の実装はSRPに違反しており、この原則を守るためにコードをリファクタリングする方法を示す絶好の機会となっています。
Timは、初期クラス内の複数の責任を強調することで、SRPを説明します:
1.ユーザーインタラクション: ウェルカムメッセージやプロンプトの処理。 2.データキャプチャ:ユーザーの姓名をキャプチャすること。 3.バリデーション:入力名を検証します。 4.ユーザー名生成:入力された名前からユーザー名を生成します。
これらの責任はそれぞれ、SRPに違反してクラスを変更する異なる理由を表しています。
Timは、各責任を独自のクラスに抽出することによって、SRPに従うようにコードをリファクタリングする方法を示します。 このアプローチにより、各クラスの変更理由が1つになり、コードがモジュール化され、保守が容易になります。
ティムは、リファクタリングの実践的な例を提供します:
using System;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Welcome to my application");
Console.Write("Enter your first name: ");
string firstName = Console.ReadLine();
Console.Write("Enter your last name: ");
string lastName = Console.ReadLine();
if (string.IsNullOrWhiteSpace(firstName) || string.IsNullOrWhiteSpace(lastName))
{
Console.WriteLine("You did not give us valid information!");
Console.ReadLine();
return;
}
var userName = $"{firstName.Substring(0, 1)}{lastName}".ToLower();
Console.WriteLine($"Your username is {userName}");
Console.WriteLine("Press enter to close...");
Console.ReadLine();
}
}Imports System
Module Program
Sub Main(args As String())
Console.WriteLine("Welcome to my application")
Console.Write("Enter your first name: ")
Dim firstName As String = Console.ReadLine()
Console.Write("Enter your last name: ")
Dim lastName As String = Console.ReadLine()
If String.IsNullOrWhiteSpace(firstName) OrElse String.IsNullOrWhiteSpace(lastName) Then
Console.WriteLine("You did not give us valid information!")
Console.ReadLine()
Return
End If
Dim userName = $"{firstName.Substring(0, 1)}{lastName}".ToLower()
Console.WriteLine($"Your username is {userName}")
Console.WriteLine("Press enter to close...")
Console.ReadLine()
End Sub
End Moduleまず、Timはユーザーに表示される標準的なメッセージを処理するクラスを作成します。 このクラスでは、ウェルカムメッセージとエンドメッセージを管理します。
public class StandardMessages
{
public static void WelcomeMessage()
{
Console.WriteLine("Welcome to my application");
}
public static void EndApplication()
{
Console.WriteLine("Press enter to close...");
Console.ReadLine();
}
public static void ShowValidationErrorMessage()
{
Console.WriteLine("You did not give us valid information!");
}
}Public Class StandardMessages
Public Shared Sub WelcomeMessage()
Console.WriteLine("Welcome to my application")
End Sub
Public Shared Sub EndApplication()
Console.WriteLine("Press enter to close...")
Console.ReadLine()
End Sub
Public Shared Sub ShowValidationErrorMessage()
Console.WriteLine("You did not give us valid information!")
End Sub
End ClassProgram クラスで、Console.WriteLine と Console.ReadLine の直接呼び出しを StandardMessages クラスのメソッドの呼び出しに置き換えてください:
class Program
{
static void Main(string[] args)
{
StandardMessages.WelcomeMessage();
// Other code...
StandardMessages.EndApplication();
}
}Module Program
Sub Main(args As String())
StandardMessages.WelcomeMessage()
' Other code...
StandardMessages.EndApplication()
End Sub
End Module次に、Timは人物の姓と名をキャプチャするクラスを作成します。 このクラスはユーザー入力を収集し、Person オブジェクトを返します。
public class PersonDataCapture
{
public static Person Capture()
{
Person output = new Person();
Console.Write("Enter your first name: ");
output.FirstName = Console.ReadLine();
Console.Write("Enter your last name: ");
output.LastName = Console.ReadLine();
return output;
}
}Public Class PersonDataCapture
Public Shared Function Capture() As Person
Dim output As New Person()
Console.Write("Enter your first name: ")
output.FirstName = Console.ReadLine()
Console.Write("Enter your last name: ")
output.LastName = Console.ReadLine()
Return output
End Function
End Classまた、ユーザーの姓と名を保持する Person クラスも必要です。
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}Public Class Person
Public Property FirstName As String
Public Property LastName As String
End ClassProgram クラスで、ユーザー入力を直接処理する部分を PersonDataCapture.Capture.Capture の呼び出しに置き換えます:
class Program
{
static void Main(string[] args)
{
StandardMessages.WelcomeMessage();
Person user = PersonDataCapture.Capture();
// Other code...
StandardMessages.EndApplication();
}
}Module Program
Sub Main(args As String())
StandardMessages.WelcomeMessage()
Dim user As Person = PersonDataCapture.Capture()
' Other code...
StandardMessages.EndApplication()
End Sub
End Module次に、Timは人物の姓と名のバリデーションを処理するクラスを作成します。 このクラスは、名前にヌルや空白がないことを確認する責任があります。
public class PersonValidator
{
public static bool Validate(Person person)
{
if (string.IsNullOrWhiteSpace(person.FirstName))
{
StandardMessages.ShowValidationErrorMessage("first name");
return false;
}
if (string.IsNullOrWhiteSpace(person.LastName))
{
StandardMessages.ShowValidationErrorMessage("last name");
return false;
}
return true;
}
}Public Class PersonValidator
Public Shared Function Validate(person As Person) As Boolean
If String.IsNullOrWhiteSpace(person.FirstName) Then
StandardMessages.ShowValidationErrorMessage("first name")
Return False
End If
If String.IsNullOrWhiteSpace(person.LastName) Then
StandardMessages.ShowValidationErrorMessage("last name")
Return False
End If
Return True
End Function
End ClassProgram クラスで、検証コードを PersonValidator.Validate の呼び出しに置き換えます:
class Program
{
static void Main(string[] args)
{
StandardMessages.WelcomeMessage();
Person user = PersonDataCapture.Capture();
if (!PersonValidator.Validate(user))
{
StandardMessages.EndApplication();
return;
}
// Other code...
StandardMessages.EndApplication();
}
}Module Program
Sub Main(args As String())
StandardMessages.WelcomeMessage()
Dim user As Person = PersonDataCapture.Capture()
If Not PersonValidator.Validate(user) Then
StandardMessages.EndApplication()
Return
End If
' Other code...
StandardMessages.EndApplication()
End Sub
End ModuleTimは、ユーザー名生成とアカウント作成ロジックを新しいAccountGeneratorクラスに移動します。
1.AccountGeneratorクラスの作成:
public class AccountGenerator
{
public static void CreateAccount(Person user)
{
string username = $"{user.FirstName.Substring(0, 1)}{user.LastName}".ToLower();
Console.WriteLine($"Your username is: {username}");
}
}
1.メインクラスの更新:
class Program
{
static void Main(string[] args)
{
StandardMessages.WelcomeMessage();
Person user = PersonDataCapture.Capture();
bool isUserValid = PersonValidator.Validate(user);
if (!isUserValid)
{
StandardMessages.EndApplication();
return;
}
AccountGenerator.CreateAccount(user);
StandardMessages.EndApplication();
}
}Module Program
Sub Main(args As String())
StandardMessages.WelcomeMessage()
Dim user As Person = PersonDataCapture.Capture()
Dim isUserValid As Boolean = PersonValidator.Validate(user)
If Not isUserValid Then
StandardMessages.EndApplication()
Return
End If
AccountGenerator.CreateAccount(user)
StandardMessages.EndApplication()
End Sub
End Module
この結びのセクションでは、Tim Coreyがデモコードのリファクタリングプロセスを通して、単一責任原則(SRP)の利点と実装を要約します。 彼は、アプリケーションをより小さく、焦点を絞ったクラスに分割することの利点を強調しています。
1.簡易コードメンテナンス:
各クラスは、変更が必要な箇所を見つけやすくするために、1つの責任を持っています。 例えば、ユーザーデータ取得ロジックは、PersonDataCaptureの下に明確に配置されます。
このような構成にすることで、ユーザー検証を変更したい人は誰でもPersonValidatorを確認することがわかるため、理解が簡単になります。
2.読みやすさの向上:
StandardMessages.WelcomeMessage();
Person user = PersonDataCapture.Capture();
bool isUserValid = PersonValidator.Validate(user);
if (!isUserValid)
{
StandardMessages.EndApplication();
return;
}
AccountGenerator.CreateAccount(user);
StandardMessages.EndApplication();
3.複雑さを軽減:
少人数制のクラスはコード行数が少なく、理解しやすく保守しやすい傾向があります。
例StandardMessagesクラスのメソッドは簡潔で、ウェルカムメッセージの表示やアプリケーションの終了など、単一の目的を果たします。
public class StandardMessages
{
public static void WelcomeMessage()
{
Console.WriteLine("Welcome to my application");
}
public static void EndApplication()
{
Console.WriteLine("Press enter to close...");
Console.ReadLine();
}
public static void ShowValidationErrorMessage(string fieldName)
{
Console.WriteLine($"You did not give us a valid {fieldName}!");
}
}

1.コード変更の容易さ:
各クラスの変更理由は1つであるため、新しい要件に応じてコードを修正するのは簡単です。
例要件が終了メッセージを変更することである場合、変更はStandardMessages.EndApplicationメソッドでのみ発生します。
2.より良いデバッグとコラボレーション:
小さくてよく定義されたクラスでは、問題の場所を簡単に特定できるため、デバッグが簡単になります。
新しい開発者は、各クラスの明確な構造と責任を理解することで、より迅速に参加することができます。
Timは、SRPを適用するとクラスが多すぎてプロジェクトが煩雑になるという一般的な懸念に対処します:
1.ナビゲーションと理解:
Visual Studioのインテリセンスのようなツールは、複数のクラスを簡単にナビゲートします。 例えば、F12を押すと、メソッドやクラスの定義に直接移動します。
小さく管理しやすい部分をたくさん持つことで、大規模なモノリシッククラスに比べて、アプリケーション全体の理解が容易になります。
2.パフォーマンスとストレージ:
3.バランスと過剰:
ティムはバランスを取るようアドバイスしています。 クラスの責任が大きくなりすぎる場合は、変更する理由が複数あるかどうかを検討し、さらに分割する必要があることを示します。
Visual Studioでクラスを広範囲にスクロールする必要がある場合、サイズが大きすぎて分割が必要になることがあります。
Timは、特に既存のコードベースにおいて、SRPを徐々に適用することを開発者に奨励しています。 SRPの原則に沿うように、小さな変更や新しいコードから始めてください。 この漸進的なアプローチは、よりスムーズな移行と継続的な改善を保証します。
ティム・コーリーのリファクタリングの例は、単一責任原則(SRP)を遵守することで、よりクリーンで保守性の高いコードが得られることを示しています。 開発者は、責任をより小さく、焦点を絞ったクラスに分割することで、コードベース内の可読性、デバッグ、コラボレーションを向上させることができます。 このSOLIDデザインパターンの基本原則は、ソフトウェア開発におけるより高度な原則とベストプラクティスへの道を開くものです。
より詳細な情報とコード・サンプルについては、ビデオをご覧ください。また、チャンネルでは、デザイン・パターンのビデオをご覧いただけます。
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!
Join our newsletter, you’ll get exclusive access on article updates. We value your privacy