Doubanfm 의 디자인 모델 (1)
46638 단어 디자인 모드
2 판 은 비교적 많은 의존 주입 을 사용 하여 Messenger 에 익숙 해 졌 고 나중에 쓸 수록 커 질 수록 느낌 이 좋 지 않 으 니 빨리 멈 춰 라.이제 각 모듈 에 대해 잘 생각해 보 겠 습 니 다.
Http 요청 에 있어 서 Restful 을 알 고 사용 할 기회 가 없 었 습 니 다. Restful 은 괜 찮 을 것 같 습 니 다. 하지만 저 는 Http 요청 에 아래 의 디자인 모델 을 사 용 했 습 니 다.
공장 방법
1. 추상 제품
UML 은 시간 이 있 으 면 다시 그리고 코드 를 먼저 올 립 니 다.
Rx 를 사용 하여 추상 적 인 Get 제품 을 만 듭 니 다. 다음 과 같 습 니 다.
1 public abstract class HttpGetMethodBase<T>
2 {
3 public virtual IObservable<T> Get(string Url)//
4 {
5 //
6 //
7 //
8 // Override
9 var func = Observable.FromAsyncPattern<HttpWebRequest, T>(Webrequest, WebResponse);
10 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(Url);
11 return func(request);
12 }
13 private IAsyncResult Webrequest(HttpWebRequest request, AsyncCallback callbcak, object ob)
14 {
15 return request.BeginGetResponse(callbcak, request);
16 }
17
18 // get,WebResponse
19 protected abstract T WebResponse(IAsyncResult result);
20 }
추상 적 인 제품 으로서 Get 방법 과 같은 방법 을 공유 할 수 있다.다시 쓸 건 WebResponse 입 니 다.
2. 구체 적 인 제품
(1) stream 제품 반환
1 public class HttpGetStream : HttpGetMethodBase<Stream>
2 {
3 protected override Stream WebResponse(IAsyncResult result)
4 {
5 try
6 {
7 var request = result.AsyncState as HttpWebRequest;
8 HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
9 #region ignore
10 if (response.Cookies != null)
11 {
12 foreach (Cookie cookie in response.Cookies)
13 {
14 Debug.WriteLine(cookie.Value);
15 }
16 }
17 Debug.WriteLine(response.ContentType);
18 Debug.WriteLine(response.StatusDescription);
19 if (response.Headers["Set-Cookie"] != null)
20 {
21 //setting may write
22 Debug.WriteLine(response.Headers["Set-Cookie"]);
23 }
24 #endregion
25 return response.GetResponseStream();
26 }
27 catch
28 {
29 Debug.WriteLine("WEBERROR");
30 return null;
31 }
32 }
33 }
(2) string 제품 반환
1 public class HttpGetString : HttpGetMethodBase<string>
2 {
3 protected override string WebResponse(IAsyncResult result)
4 {
5 try
6 {
7 var request = result.AsyncState as HttpWebRequest;
8 HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
9 #region ignore
10 if (response.Cookies != null)
11 {
12 foreach (Cookie cookie in response.Cookies)
13 {
14 Debug.WriteLine(cookie.Value);
15 }
16 }
17 Debug.WriteLine(response.ContentType);
18 Debug.WriteLine(response.StatusDescription);
19 if (response.Headers["Set-Cookie"] != null)
20 {
21 //setting may write
22 Debug.WriteLine(response.Headers["Set-Cookie"]);
23 }
24 #endregion
25 Stream stream = response.GetResponseStream();
26 using (StreamReader sr = new StreamReader(stream))
27 {
28 return sr.ReadToEnd();
29 }
30 }
31 catch
32 {
33 Debug.WriteLine("WEBERROR");
34 return null;
35 }
36 }
37 }
(3) 비트 맵 을 되 돌려 주 는 제품
1 public class HttpGetBitmapImage : HttpGetMethodBase<BitmapImage>
2 {
3 protected override BitmapImage WebResponse(IAsyncResult result)
4 {
5 try
6 {
7 var request = result.AsyncState as HttpWebRequest;
8 HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
9 #region ignore
10 if (response.Cookies != null)
11 {
12 foreach (Cookie cookie in response.Cookies)
13 {
14 Debug.WriteLine(cookie.Value);
15 }
16 }
17 Debug.WriteLine(response.ContentType);
18 Debug.WriteLine(response.StatusDescription);
19 if (response.Headers["Set-Cookie"] != null)
20 {
21 //setting may write
22 Debug.WriteLine(response.Headers["Set-Cookie"]);
23 }
24 #endregion
25 Stream stream = response.GetResponseStream();
26 BitmapImage bitmapimage = new BitmapImage();
27 bitmapimage.SetSource(stream);
28 return bitmapimage;
29 }
30 catch
31 {
32 Debug.WriteLine("WEBERROR");
33 return null;
34 }
35 }
36 }
지금 은 주로 세 가지 제품 이 있 는데 나중에 오디 오 로 돌아 가 는 제품 이 있 으 면 그대로 옮 겼 으 면 좋 겠 습 니 다. 이렇게 하면 확장 이 편리 합 니 다.
3. 인터페이스 공장 (추상 공장 이 아니 라 추상 공장 모델 과 충돌 할 까 봐)
(1) 대상 (제품) 을 만 드 는 인터페이스
interface IHttpGet<T>
{
HttpGetMethodBase<T> CreateHttpRequest();
}
(2) 구체 적 인 공장
구체 적 인 공장 은 모두 구체 적 인 제품 을 만 드 는 데 쓰 인 다.
1. string (get) 공장
1 public class StringHttpFactory:IHttpGet<string>
2 {
3 public HttpGetMethodBase<string> CreateHttpRequest()
4 {
5 return new HttpGetString();
6 }
7 }
2. stream (get) 공장
1 public class StreamHttpFactory : IHttpGet<Stream>
2 {
3
4 public HttpGetMethodBase<Stream> CreateHttpRequest()
5 {
6 return new HttpGetStream();
7 }
8 }
3. 비트 맵 공장
1 public class BitmapImageHttpFactory : IHttpGet<BitmapImage>
2 {
3 public HttpGetMethodBase<BitmapImage> CreateHttpRequest()
4 {
5 return new HttpGetBitmapImage();
6 }
7 }
클 라 이언 트 호출:
클 라 이언 트 호출 은 구체 적 인 공장 모델 을 알 아야 하기 때문에 여 기 는 제 가 물음 표를 찍 고 코드 를 먼저 보 겠 습 니 다.
1 IHttpGet<string> factory = new StringHttpFactory();//string
2 factory.CreateHttpRequest().Get("http://douban.fm/j/mine/playlist?from=mainsite&channel=0&kbps=128&type=n").Subscribe(
3 (result) =>
4 {
5 7 });
코드 new 는 구체 적 인 공장 을 만 들 었 습 니 다. 여 기 는 진정한 디 결합 에 이 르 지 못 했 기 때문에 나중에 할 수 있 는 지 없 는 지 를 고려 합 니 다.
1。프로필 반사 처리
2. 주입 에 의존한다.
//to be continued................
직책 체인
배경 부터 봐.
Newtonsoft 의 제 이 슨 라 이브 러 리 를 사용 하면 시원 하지만 복잡 한 제 이 슨 스 트 링 에 직면 하면 그 변화 에 잘 대처 하지 못 한다. 변화 점 은 'J Token [] [] [] [] [] [] [] []] []' 중 괄호 의 개 수 는 알 수 없다. 나 는 언제 나 오 는 제 이 슨 스 트 링 이 몇 개 있 을 지 모른다. 제 이 슨 스 트 링 을 해석 하 는 곳 이 많 으 면 이 중 괄호 의 수량 이 매우 많 을 것 이다.너무 징 그 러 워 보 여요.물론 뉴턴 소프트 에 게 해결책 이 있 을 지 모 르 지만 나 는 찾 지 못 했다.
1. 제 이 슨 꼬치 의 다양성
json 문자열 은 웹 서버 에서 배정 한 것 으로 각종 이름, 각종 key / vaule, 클 라 이언 트 는 이러한 변화 에 대응 하기 어렵다.
직책 체인 의 효 과 는 클 라 이언 트 가 얻 은 json 문자열 만 보 내 면 이에 대응 하 는 클래스 를 얻 을 수 있 습 니 다. json 문자열 이 어떻게 처리 되 는 지 클 라 이언 트 는 모 릅 니 다.
상위 코드
1 public abstract class RequestorBase<T>
2 {
3 protected RequestorBase<T> Successor;
4 internal void SetSucessor(RequestorBase<T> suc)
5 {
6 Successor = suc;
7 }
8 public abstract T ProcessRequest(string json);// ,
9 }
10 public class Requestor1<T> : RequestorBase<T>
11 {
12 public override T ProcessRequest(string json)
13 {
14 try
15 {
16 return JsonConvert.DeserializeObject<T>(JToken.Parse(json)["song"].ToString());
17 }
18 catch
19 {
20 Debug.WriteLine(" ");
21 return Successor.ProcessRequest(json);
22 }
23 }
24 }
25 public class Requestor2<T> : RequestorBase<T>
26 {
27 public override T ProcessRequest(string json)
28 {
29 try
30 {
31 return JsonConvert.DeserializeObject<T>(JToken.Parse(json)["song"][0].ToString());
32 }
33 catch
34 {
35 Debug.WriteLine(" ");
36 return Successor.ProcessRequest(json);
37 }
38 }
39 }
40 public class Requestor3<T> : RequestorBase<T>
41 {
42 public override T ProcessRequest(string json)
43 {
44 Debug.WriteLine(" , Default");
45 return default(T);
46 //NO Chain
47 }
48 }
서로 다른 직책 자 는 서로 다른 제 이 슨 꼬치 해석 을 한다.
그리고 사용 하 세 요.
단일 모드
단일 모드 를 사용 하여 관리 직책 체인 을 만 들 고 단일 관리 직책 체인 을 사용 하 는 목적 은 직책 체인 이 json 문자열 만 처리 하 는 것 이다. 그들 은 모두 상태 가 없 으 며 그들의 방법 을 메모리 에 불 러 오 면 된다.
1 public class ManagerResponsibilityChain<T>
2 {
3 static private RequestorBase<T> _startrequestor;
4 static public RequestorBase<T> Instance_Startrequestor
5 {
6 get
7 {
8 if (_startrequestor == null)
9 {
10 Inital();
11 }
12 return _startrequestor;
13 }
14 }
15 private ManagerResponsibilityChain()
16 {
17
18 }
19 static private void Inital()
20 {
21 _startrequestor = new Requestor1<T>();
22 var secondrequestor = new Requestor2<T>();
23 var thridrequestor = new Requestor3<T>();
24 _startrequestor.SetSucessor(secondrequestor);
25 secondrequestor.SetSucessor(thridrequestor);//requestor3 is the end
26 }
27 }
오늘 은 여기까지.
뒤에 추가:
위의 직책 체인 에 대해 직책 자 를 늘 리 려 면 증가 하 는 과정 을 잊 어 버 리 고 마지막 두 번 째 부분 에 삽입 한 다음 에 두 개의 직책 체인 을 다시 설정 해 야 한다.
1 public class ManagerResponsibilityChain<T>
2 {
3 static private RequestorBase<T> _startrequestor;
4 static public RequestorBase<T> Instance_Startrequestor
5 {
6 get
7 {
8 if (_startrequestor == null)
9 {
10 Inital();
11 }
12 return _startrequestor;
13 }
14 }
15 private ManagerResponsibilityChain()
16 {
17
18 }
19 static public List<RequestorBase<T>> RequestList=new List<RequestorBase<T>>();
20 static private void InsertARequestor(RequestorBase<T> InsertItem)
21 {
22 RequestList.Insert(RequestList.Count - 1, InsertItem);
23 InsertItem.SetSucessor(RequestList[RequestList.Count - 1]);
24 RequestList[RequestList.Count - 3].SetSucessor(InsertItem);
25
26 }
27
28
29 static private void Inital()
30 {
31
32 _startrequestor = new Requestor1<T>();
33 var secondrequestor = new Requestor2<T>();
34 var thridrequestor = new Requestor3<T>();
35 RequestList.Add(_startrequestor);
36 RequestList.Add(secondrequestor);
37 RequestList.Add(thridrequestor);
38 _startrequestor.SetSucessor(secondrequestor);
39 secondrequestor.SetSucessor(thridrequestor);//requestor3 is the end
40
41
42 InsertARequestor(new Requestor4<T>());
43 InsertARequestor(new Requestor5<T>());
44 InsertARequestor(new Requestor6<T>());
45 }
46
47 }
혹은
1 public class ManagerResponsibilityChain<T>
2 {
3 static private RequestorBase<T> _startrequestor;
4 static public RequestorBase<T> Instance_Startrequestor
5 {
6 get
7 {
8 if (_startrequestor == null)
9 {
10 Inital();
11 }
12 return _startrequestor;
13 }
14 }
15 private ManagerResponsibilityChain()
16 {
17
18 }
19
20 static private void InsertARequestor(RequestorBase<T> InsertItem, List<RequestorBase<T>> RequestList)
21 {
22 RequestList.Insert(RequestList.Count - 1, InsertItem);
23 InsertItem.SetSucessor(RequestList[RequestList.Count - 1]);
24 RequestList[RequestList.Count - 3].SetSucessor(InsertItem);
25
26 }
27
28
29 static private void Inital()
30 {
31 List<RequestorBase<T>> RequestList = new List<RequestorBase<T>>();
32 _startrequestor = new Requestor1<T>();
33 var secondrequestor = new Requestor2<T>();
34 var thridrequestor = new Requestor3<T>();
35 RequestList.Add(_startrequestor);
36 RequestList.Add(secondrequestor);
37 RequestList.Add(thridrequestor);
38 _startrequestor.SetSucessor(secondrequestor);
39 secondrequestor.SetSucessor(thridrequestor);//requestor3 is the end
40
41
42 InsertARequestor(new Requestor4<T>(), RequestList);
43 InsertARequestor(new Requestor5<T>(), RequestList);
44 InsertARequestor(new Requestor6<T>(), RequestList);
45 }
46
47 }
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
디자인 모델 의 공장 모델, 단일 모델자바 는 23 가지 디자인 모델 (프로 그래 밍 사상/프로 그래 밍 방식) 이 있 습 니 다. 공장 모드 하나의 공장 류 를 만들어 같은 인 터 페 이 스 를 실현 한 일부 종 류 를 인 스 턴 스 로 만 드 는 것...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.