최근 회사의 사양을 정리했는데, 그 중 "함수의 매개변수 개수는 4개를 넘지 않아야 한다"는 내용이 홍보 과정에서 다소 논란이 됐다. 논란의 여지가 있지만, 그렇게 하면 프로그래밍 시 어려움을 겪을 수 있으며, 그럴 가치가 있는지에 대한 논쟁이 있습니다. 함수를 사용하는 사람들이 더 쉽게 사용할 수 있도록 이 작업을 수행하는 것이 가치가 있다고 생각합니다. 프로그래밍의 어려움은 종종 매개 변수를 줄이는 몇 가지 방법에 익숙하지 않기 때문입니다.
1. 구조를 사용하여 매개변수 캡슐화
예: 사용자 추가
원래 함수 본문: AddUser(문자열 userName, 문자열 비밀번호, 문자열 주소, 문자열 전화, int age)
리팩터링: User 클래스를 추가합니다.
클래스 사용자
{
공개 문자열 사용자 이름 { 설정 }
공개 문자열 비밀번호 { 설정 }
공개 문자열 주소 { 가져오기 }
공개 문자열 전화 { 설정 }
공개 int 연령 { 설정 }
}
AddUser를 다음으로 변경: AddUser(사용자 사용자)
문제: 추가된 클래스가 다른 곳에서 사용되지 않으면 그만한 가치가 없다고 느끼는 경우가 많습니다. 이때 익명 클래스를 사용하여 매개변수를 캡슐화하는 것을 고려할 수 있습니다.
2. 속성을 사용하여 매개변수 대체
1의 AddUser 메서드가 User 클래스에 배치되면 AddUser 메서드의 사용자 매개 변수를 생략할 수 있습니다. 때로는 일부 메서드의 매개 변수 수를 줄이기 위해 일부 특성을 추가할 수도 있습니다. 객체지향 설계에서는 객체가 스스로 책임을 져야 하며, 책임이 명확하게 정의되어야 합니다. 메소드에 매개변수가 너무 많은 이유는 메소드가 존재해서는 안 되는 곳에 작성되었기 때문일 수 있습니다. GRASP 원칙에서 언급된 "정보 전문가" 모델은 많은 경우 매개변수 수를 줄일 수 있습니다.
예: 계좌 이체
기존 기능: 이체(계좌에서,계좌에서,소수 화폐)
리팩토링:
암호
공개 클래스 TransferProcess
{
개인 계정 보낸 사람;
개인 계정 대상;
공개 TransferProcess(계정에서, 계정으로)
{
this.From = from;
this.To = to;
}
공공 무효 이체(소수화폐)
{
if (money<From.Money)
{
From.Money = From.Money - 돈;
To.Money = To.Money + 돈;
//데이터베이스 업데이트
}
또 다른
{
throw new Exception("잔액 초과");
}
}
}
참고: 정보 전문가 패턴은 객체 지향 설계의 가장 기본 원칙입니다. 객체(클래스)를 설계할 때 클래스가 특정 책임을 수행하는 데 필요한 모든 정보를 갖고 있으면 이 책임을 이 클래스에 할당하여 구현해야 합니다. . 이때 본 직급은 이러한 책임에 해당하는 정보전문가이다.
3. 비공개 기능을 사용하세요
함수를 호출할 때는 대화형 매개변수가 많이 필요하지 않은 경우가 많지만, 매개변수를 제공할 때는 모든 조건을 제공해야 합니다. 이때 함수를 분류하고 가장 복잡한 함수를 비공개로 캡슐화하고 노출할 수 있습니다. 간단한 함수. 함수를 완성하려면 이러한 복잡한 함수를 호출하세요. mvc에서 TextBox 메서드의 구현을 살펴보겠습니다.
암호
public static string TextBox(this HtmlHelper htmlHelper, 문자열 이름, 개체 값, IDictionary<string, object> htmlAttributes) {
return InputHelper(htmlHelper, InputType.Text, 이름, 값, (값 == null) /* useViewData */, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes);
}
private static string InputHelper(this HtmlHelper htmlHelper, InputType inputType, 문자열 이름, 객체 값, bool useViewData, bool isChecked, bool setId, bool isExplicitValue, IDictionary<string, object> htmlAttributes) {
if (String.IsNullOrEmpty(이름)) {
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
}
TagBuilder tagBuilder = new TagBuilder("입력");
... ...
그러나 때로는 호출자에게 최대한의 유연성을 제공하기 위해 가장 복잡한 함수 오버로딩을 노출할 수도 있습니다.
4. params 키워드
매개변수 개수가 가변적인 경우 매개변수의 메소드 매개변수가 사용되도록 지정합니다.
용법:
암호
정적 무효 Main(string[] args)
{
UseParams(1, 2, 3);
}
공개 정적 무효 UseParams(params int[] 목록)
{
for (int i = 0; i < list.Length; i++)
{
Console.WriteLine(목록[i]);
}
Console.WriteLine();
}
이 방법은 실제로 매개변수 수를 줄이지 않고 함수 본문만 단순화합니다.
5. 익명 클래스를 사용하여 매개변수 캡슐화
준비 지식: 먼저 RouteValueDictionary를 살펴보겠습니다.
암호
정적 무효 Main(string[] args)
{
RouteValueDictionary r = new RouteValueDictionary(new { id=1,name="lfm"});
foreach(r의 var 항목)
{
Console.WriteLine("{0}:{1}", item.Key, item.Value);
}
//Console.WriteLine();
}
결과:
아이디:1
이름:lfm
RouteValueDictionary는 인스턴스의 속성 이름과 속성 값을 사전에 저장할 수 있습니다.
mvc의 많은 곳에서 이 방법을 사용하여 매개변수를 전달합니다.
예: <%= Html.ActionLink("Details", "Details", new { id=item.id })%>
ActionLink 메서드 본문에서 RouteValueDictionary는 익명 개체를 분해한 다음 링크에 조합하는 데 사용됩니다.