디자인 모델 의 행위 유형 01
우 리 는 창설 형 모델, 구조 형 모델 을 거 쳐 디자인 모델 의 종착역 인 행위 형 모델 에 도착 했다.
다음 에 우리 가 말 하 는 일부 모델 은 주로 대상 이나 유형 간 의 행위 와 직책 에 관심 을 가지 고 혼 란 스 러 운 코드 논리 가 유지 비용 을 증가 하지 않도록 하 는 것 이다.
책임 체인 모드
책임 체인 은 근본적으로 링크 구조 이다. 우 리 는 체인 의 맨 끝 에서 책임 져 야 할 노드 를 찾 아야 한다. 만약 에 현재 노드 가 사물 을 처리 하면 우 리 는 더 이상 찾 지 않 을 것 이다.
예 를 들 어 하나의 지주 게임 에서 우 리 는 게이머 들 이 선택 한 몇 장의 카드 가 규칙 에 부합 되 는 지 판단 해 야 한다. 우 리 는 카드 규칙 책임 체인 을 만들어 하나의 규칙 으로 판단 해 야 한다.
public class Card
{
public int Number { get; set; }
}
public enum CardSuit
{
Spade, Heart, Club, Diamond
}
public abstract class CardRuleDetectionBase
{
public abstracct bool Handle(Card[] cards);
public CardRuleDetectionBase Next { get; set; }
}
지금 우 리 는 카드 의 규칙 책임 체인 을 만 듭 니 다.
public class SingleCardRule : CardRuleDetection
{
public override bool Handle(Card[] cards)
{
if(cards.Length == 1)
return true;
return false;
}
}
public class DoubleCardRule : CardRuleDetection
{
public override bool Handle(Card[] cards)
{
if(cards.Length == 2 && cards[0].Number == cards[1].Number)
return true;
return false;
}
}
public class TripleCardRule : CardRuleDetection
{
public override bool Handle(Card[] cards)
{
if(cards.Length == e && cards[0].Number == cards[1].Number && cards[1].Number == cards[2].Number)
return true;
return false;
}
}
마지막 으로 이렇게 썼어 요.
public class Program
{
public static void Main(string[] args)
{
var sr = new SingleCardRule();
sr.Next = new DoubleCardRule();
sr.Next.Next = new TripleCardRule();
var cards = new []
{
new Card() { Number = 2 },
new Card() { Number = 2 },
new Card() { Number = 2 }
};
Console.WriteLine(IsCardValid(cards, sr)); // true
cards = new []
{
new Card() { Number = 13 }
};
Console.WriteLine(IsCardValid(cards, sr)); // true
cards = new []
{
new Card() { Number = 3 },
new Card() { Number = 4 },
new Card() { Number = 5 },
new Card() { Number = 6 },
new Card() { Number = 7 }
};
Console.WriteLine(IsCardValid(cards, sr)); // false
}
public static void IsCardValid(Card[] cards, CardRuleDetection rule)
{
do
{
if(rule.Handle(cards))
return true;
rule = rule.Next;
}
while(rule != null);
return false;
}
}
이런 체인 모드 는 제 가 별로 좋아 하지 않 아 요. 배열 해도 되 잖 아 요.
public class Program
{
public static void Main(string[] args)
{
var rules = new CardRuleDetection[]
{
new SingleCardRule(),
new DoubleCardRule(),
new TripleCardRule()
};
var cards = new []
{
new Card() { Number = 2 },
new Card() { Number = 2 },
new Card() { Number = 2 }
};
Console.WriteLine(IsCardValid(rules, cards)); // true
}
public static void IsCardValid(CardRuleDetection[] rules, Card[] cards)
{
foreach(var r in rules)
{
if(r.Handle(cards))
return true;
}
return false;
}
}
명령 모드
명령 모델 은 우리 가 복잡 하고 변화 가 많은 요구 에 대응 하 는 상황 을 해결 할 수 있다. 예 를 들 어 한 회사 의 행정 부가 처리 해 야 할 것 은 매우 복잡 하 다. 만약 에 행정 부서 가 한 사람 만 있 고 그 가 하 는 일이 확실 하지 않 으 면 휴가 청구 절차 등 절차 가 변화 한 후에 그 사람 을 골 치 아 프 게 할 것 이다.
이상 적 인 상태 에서 우 리 는 이렇게 해 야 한다. 모든 일 은 숙련 된 사람 이 해 야 한다. 만약 에 이 일의 절차 가 변화 한다 면 이 사람 을 떼 어 놓 고 새로운 절 차 를 잘 아 는 사람 을 불 러 서 해 야 한다. 그리고 행정 부 서 는 주문 형식 으로 업 무 를 처리 하고 모든 사물 은 하나의 요구 내용 을 포함한다. 그러면 모든 일 을 효율적으로 처리 할 수 있다.
그러나 이런 이념 은 현실 에서 실현 불가능 할 것 이다. 그러나 절차 세계 에서 충분히 실현 할 수 있다.
우선 우 리 는 주문 처리 절 차 를 정의 합 니 다.
public interface IOrderCommand where T : Order
{
string OrderName { get; }
void Handle(T request);
}
public class Order
{
public Order(string orderName)
{
OrderName = orderName;
}
public string OrderName { get; private set; }
}
public class OrderDispatch
{
private List commands = new List();
public void RegisterCommand(IOrderCommand h)
{
commands.Add(h);
}
public void Handle(Order order)
{
foreach(var c in commands)
{
if(o.OrderName == c.OrderName)
{
c.Handle(o);
break;
}
}
}
}
우 리 는 평소에 우리 회사 의 행정 업 무 를 모 의 해 보 자.
//
public class PackageOrder : Order
{
public PackageOrder() : base("package") { }
public Package Package { get; set; }
}
public class PackageNotifyCommand : IOrderCommand
{
public PackageNotifyCommand(QQGroup group)
{
this.group = group;
}
private QQGroup group;
public string OrderName { get { return "package"; } }
public void Handle(PackageOrder order)
{
var qqPersion = group.FindName(order.Package.Receiver);
if(qqPerson != null)
qqPerson.SendText(" ~");
}
}
//
public class ReimbursementOrder : Order
{
public ReimbursementOrder() : base("reimbursement") { }
public Person Person { get; set; }
public String Type { get; set; }
public float Amount { get; set; }
}
public class ReimbursementCommand : IOrderCommand
{
public ReimbursementCommand(Cashier cashier)
{
this.cashier = cashier;
}
private Cashier cashier;
public void Handle(ReimbursementOrder order)
{
if(order.Type == "food")
return;
var money = cashier.Request(order.Amount, order.Person.Name + ": "+order.Type);
order.Person.Give(money);
}
}
마지막 으로 응용 장면 을 모 의 해 보 겠 습 니 다.
public void Main()
{
var dispatch = new OrderDispatch();
var pnc = new PackageNotifyCommand(new QQGroup("XXX "));
var rc = new ReimbursementCommand(new Cashier(" "));
dispatch.RegisterCommand(pnc);
dispatch.RegisterCommand(rc);
var pOrder = new PackageOrder();
var package = new Package() { Receiver = " ", content = " " };
pOrder.Package = package;
dispatch.Handle(pOrder);
var rOrder = new ReimbursementOrder();
rOrder.Person = new Person () { Name = "Jim" }
rOrder.Type = "texi";
rOrder.Amount = 20;
dispatch.Handle(rOrder);
}
만약 우리 가 가장 원시 적 인 서법 으로 돌아간다 면 어떻게 되 어야 합 니까?
public class AdminDepartment
{
public QQGroup group;
public Cashier cashier;
public void HandlePackage(Package p)
{
group.FindName(p.Receiver).SendText(" !");
}
public void HandleReimbursement(Person p, string type, float amount)
{
if(type=="food" || type == "texi")
return;
var money = cashier.Request(amount / 2, p.Name + ": "+type);
order.Person.Give(money);
}
}
이상 의 방법 은 OCP 와 SRP 를 심각하게 위반 한다.다음 중 처리 해 야 할 것 이 20 개가 넘 으 면 어떻게 합 니까?
요약: 언제 우 리 는 명령 방법 을 사용 합 니까?
명령 모드 를 사용 할 때 주의:
command 형식 은 위 인터페이스 에 있 는 Handle () 방법 을 제외 하고 다른 개방 방법 이 있어 서 는 안 됩 니 다.
해석 기 모드
략, 개인 적 인 인상 은 별로 사용 해 본 적 이 없 는 것 같 습 니 다.내 가 지정 한 데이터 (문자열 일 수도 있 고 다른 사용자 정의 데이터 일 수도 있 음) 를 마지막 으로 해석 기 를 통 해 답 을 주 겠 다 는 뜻 이다.
응용 필드:
교체 기 모드
교체 기 모드 란 무엇 입 니까?교체 기 모드 란 취 합 대상 의 각 요 소 를 순서대로 방문 하 는 방법 을 제공 하 는 것 이지 내부 의 표현 을 드 러 내 는 것 이 아니다.실제 개발 과정 에서 우 리 는 서로 다른 수 요 를 대상 으로 서로 다른 방식 으로 전체 통합 대상 을 옮 겨 다 녀 야 할 수도 있 지만 우 리 는 집적 대상 의 추상 적 인 인터페이스 층 에 다양한 편리 한 조작 이 가득 하 기 를 원 하지 않 는 다.이때 우 리 는 이런 것 이 필요 하 다. 그것 은 다음 과 같은 세 가지 기능 을 가 져 야 한다.
교체 기 라 는 것 은 C \ # 자체 테이프 입 니 다. C \ # 교체 기의 정의 가 무엇 인지 봅 시다.
public interface IEnumerable
{
IEnumerator GetEnumerator();
}
public interface IEnumerator
{
/// Gets the current element in the collection.
/// The current element in the collection.
object Current
{
get;
}
/// Advances the enumerator to the next element of the collection.
/// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection.
/// The collection was modified after the enumerator was created.
bool MoveNext();
/// Sets the enumerator to its initial position, which is before the first element in the collection.
/// The collection was modified after the enumerator was created.
void Reset();
}
원본 코드 에서 볼 수 있 듯 이 IEnumerator 는 사용자 에 게 이 대상 의 모든 구성원 을 순서대로 방문 하 는 기능 만 주 었 을 뿐 입 니 다.
중개 모드
중개 라 는 두 글 자 는 즉시 나 로 하여 금 먼저 부동산 중개 에 도착 하 게 했다.프로그램 개발 중의 중개 와 주택 중 개 는 비슷 한 상황 이 있다. 미래 에 세입 자 와 집주인 간 에 만 나 거나 의사 소통 이 불편 하 다 (예 를 들 어 여가 사건 이 일치 하지 않 고 언어 가 통 하지 않 는 문제) 는 중개 가 쌍방 을 대신 하여 의사 소통 을 완성 한다.
프로그램 개발 에서 우 리 는 A 대 시스템 의 하위 기능 중 하나 가 B 대 시스템 의 하위 기능 과 서로 소통 해 야 한 다 는 문제 에 자주 부 딪 힌 다.
그러나 A 대 기능 이 있 는 환경 과 B 대 기능 은 전혀 교 집합 되 지 않 았 다.A 는 B 를 인용 할 수 없 거나 A 는 B 를 인용 해 서 는 안 된다.이 럴 때 는 중개 모드 가 필요 하 다.
예 를 들 어 아이스크림 공장 안 에는 7 개의 큰 단계 가 있 는데 각 단계 이론 적 으로 서로 독립 되 고 서로 영향 을 주지 않 지만 연결 할 때 서로 처리 해 야 할 것들 이 나타 나 는 것 을 피하 기 어렵다.
한 접시 에 담 긴 그릇 은 여러 가지 이유 로 다음 단계 에 직접 전달 되 는 것 이 아니 라 다음 단계 에 직접 그릇 을 새로 만 드 는 것 이다.이 로 인해 감상 적 으로 두 개의 그릇 이 생 긴 상황 이다.그래서 다음 단 계 는 이전 단계 에 오래된 그릇 을 숨 기 라 고 알려 야 한다.
두 단 계 는 서로 독립 되 어 있 기 때문에 그들 은 상대방 을 쉽게 (또는 아름 답 게) 인용 할 수 없 기 때문에 우 리 는 알림 센터 라 는 종 류 를 사용 했다.
설정: 이전 단 계 는 A 이 고 다음 단 계 는 B 이 며 알림 센터 는 C 입 니 다.A 는 C 가 앞으로 보 낼 '숨 은 그릇' 의 소식 을 감청 하고 이 소식 을 들 은 후에 그릇 을 숨긴다.B. 적당 한 이벤트 에 "그릇 숨 기기" 메 시 지 를 C 에 게 보 내기;C 는 소식 을 들 은 후에 A 가 이 소식 을 필요 로 하 는 것 을 발견 하고 C 는 A 의 처리 방법 을 호출 했다.A 는 그릇 을 숨 기 는 데 성공 했다.
그래서 A 와 B 사이 의 통신 은 이렇게 생 겼 다.그러나 그들 사이 에는 직접적인 관계 가 없다.
결론: 중개 모델 을 사용 하 는 상황 은 A 와 B 가 상대방 을 아름 답 게 인용 할 수 없 거나 아름 답 게 인용 할 수 없 는 경우 이다. 이때 제3자 가 끼어 들 어 A 와 B 가 서로의 의사 소통 을 완성 해 야 한다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.