종종 여러 알고리즘 또는 구현이 동일한 작업을 올바르게 해결할 수 있습니다. 선택한 코드는 설계 의도를 보여줍니다. 코드를 읽는 개발자 및 코딩 에이전트는 해당 구조를 사용하여 사용자의 의도, 즉 각 작업에 필요한 항목, 속한 위치 및 실행 시기를 유추합니다.
Tip
이 문서는 기본 C# 식, 문 및 메서드를 알고 있는 개발자를 위한 기본 사항 섹션의 일부입니다. 프로그래밍을 처음 접하는 경우 먼저 시작 자습서로 시작 하세요.
이 섹션에서는 알고리즘에 대한 유효한 접근 방식을 비교하고 동작의 미묘한 차이점과 독자가 이를 어떻게 해석하는지를 설명합니다. 형식, 식, 문 및 메서드와 같은 친숙한 언어 요소를 결합하고 의도한 디자인을 전달하는 형태를 선택합니다.
동작 및 디자인 의도 비교
구현을 선택하기 전에 다른 코드에서 구현을 사용하는 방법을 고려합니다. 해당 코드는 호출자입니다. 입력을 제공하고 작업을 호출하며 결과를 사용합니다. 즉시 완료된 결과가 필요합니까, 아니면 값을 하나씩 처리할 수 있나요? 도우미가 이 작업만의 일부인가요, 아니면 다른 작업에서도 이를 사용합니까? 이러한 질문은 필요한 동작과 코드가 전달하는 디자인을 모두 비교하는 데 도움이 됩니다.
짧은 인라인 작업은 사용하는 위치에서 단계를 독자에게 보여 줍니다. 예를 들어 Where(task => task.Priority > 3)를 사용하면 필터링 규칙이 즉시 표시됩니다. 명명된 도우미는 Where(IsUrgent)규칙의 목적을 강조하고 독자가 세부 정보를 별도로 검사할 수 있도록 합니다. 단계 자체 또는 그 목적이 주변 코드를 가장 잘 설명하는지 여부에 따라 선택합니다.
도우미를 선언하는 위치는 의도한 범위를 전달합니다.
ShowDashboard 내부의 로컬 함수는 해당 도우미가 그 작업에 속함을 나타내고 다른 멤버가 이를 호출하지 못하도록 합니다. 포함하는 형식의 프라이빗 메서드는 다른 멤버가 도우미를 사용할 수 있게 하므로, 형식의 다른 위치에서 재사용할 것으로 예상된다는 것을 시사합니다. 둘 다 같은 계산을 정리해 보여줄 수 있지만 그 역할에 대해 독자에게 서로 다른 기대를 갖게 합니다.
도우미의 입력을 제공하는 방법은 해당 의존성을 드러냅니다. 한도를 매개 변수(예: IsUrgent(task, minimumPriority))로 전달하면 각 호출에서 해당 입력이 표시됩니다. 로컬 함수 또는 람다는 인수로 수신하지 않고 주변 범위의 변수를 사용하여 대신 캡처minimumPriority할 수 있습니다. 캡처는 도우미를 포함하는 작업의 컨텍스트에 연결합니다. 명시적 매개 변수를 사용하면 제공된 데이터를 보다 쉽게 식별할 수 있습니다.
static 주변 상태를 캡처하지 않도록 보장하려는 경우 로컬 함수 또는 람다를 사용합니다.
결과를 반환하는 방식은 작업이 언제 발생하는지를 보여줍니다. 컬렉션을 빌드하고 반환하는 메서드는 호출자가 컬렉션을 받기 전에 그 작업을 완료합니다. 반복기는 호출자가 요청할 때 요소를 생성하므로 모든 요소가 생성되기 전에 호출자가 요소 생성을 중지할 수 있습니다. 둘 다 동일한 값을 생성할 수 있지만 호출자는 완료된 결과를 받고 있는지 또는 아직 계산이 수행되지 않은 시퀀스를 수신하는지 이해해야 합니다.
각 선택에 대해 먼저 호출 코드에 필요한 동작을 식별합니다. 그런 다음 다른 개발자 또는 코딩 에이전트가 이름, 범위, 입력 및 결과를 보고 무엇을 유추할지 고려하세요. 이러한 기대치가 디자인과 일치하도록 하는 형태를 선택하고 코드의 형태만으로는 드러나지 않는 중요한 동작을 설명합니다. 목표는 모든 곳에 하나의 양식을 적용하지 않고 유효한 대안 중에서 의도적으로 선택하는 것입니다.
예제에서 디자인 선택 사항 읽어보기
다음 예제에서는 여러 선택 항목이 디자인의 서로 다른 부분을 전달하는 방법을 보여 줍니다. 긴급하고 시작할 준비가 된 작업을 표시합니다.
ProjectTask는 작업의 제목, 우선순위 및 차단 상태를 보유합니다.
var tasks = new[]
{
new ProjectTask("Confirm venue", Priority: 3, IsBlocked: false),
new ProjectTask("Print badges", Priority: 2, IsBlocked: true),
new ProjectTask("Test microphones", Priority: 2, IsBlocked: false),
};
ShowDashboard("Community meetup", tasks, minimumPriority: 2);
static void ShowDashboard(
string projectName,
IEnumerable<ProjectTask> tasks,
int minimumPriority)
{
var urgentTasks = tasks.Where(
task => task.Priority >= minimumPriority);
foreach (ProjectTask task in ReadyTasks(urgentTasks))
{
Console.WriteLine(FormatTask(task));
}
string FormatTask(ProjectTask task) =>
$"{projectName}: {task.Title}";
}
static IEnumerable<ProjectTask> ReadyTasks(
IEnumerable<ProjectTask> tasks)
{
foreach (ProjectTask task in tasks)
{
if (!task.IsBlocked)
{
yield return task;
}
}
}
record ProjectTask(string Title, int Priority, bool IsBlocked);
각 선택은 작업의 다른 부분을 명확하게 유지합니다.
- 전달된
Where람다는 이를 사용하는 작업 옆에 짧은 우선 순위 규칙을 배치합니다. - 로컬 함수
FormatTask는ShowDashboard에만 속하는 서식 지정 단계의 이름을 지정합니다. -
ReadyTasks반복기를 사용하면 호출자가 중간 컬렉션을 만들지 않고 준비된 작업을 처리할 수 있습니다. -
foreach루프는 각 결과를 작성하는 최종 작업을 명시적으로 드러냅니다.
비교하자면 이 준비 테스트는 간단한 필터이므로 Where(static task => !task.IsBlocked)가 ReadyTasks를 대체할 수 있습니다. 두 양식 모두 열거 시점까지 필터 적용을 지연합니다. 람다는 호출 위치에 규칙을 배치합니다. ReadyTasks는 규칙에 이름을 지정합니다. 독자가 누가 호출하는지 이해하는 데 도움이 되는 정보에 따라 둘 중에서 선택합니다.
다음 문서에서는 이와 같은 비교를 사용하여 각 접근 방식이 적합한 시기와 독자가 여러분의 선택에서 유추할 수 있는 사항을 설명합니다.
다음 단계
.NET