Doubanfm 의 디자인 모델 (1)

46638 단어 디자인 모드
앞의 두 판 Doubanfm 은 너무 스탬프 를 썼 고, 첫 번 째 판 은 WP 휴대 전화 에 익숙 한 API 라 고 무시 할 수 있다.
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     }

좋은 웹페이지 즐겨찾기