zoukankan      html  css  js  c++  java
  • DoubanFm之设计模式(一)

      前两版DoubanFm写的太戳,第一版可以忽略,当是熟悉WP手机的一些API。。

    第二版用了比较多的依赖注入,熟悉了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的json库很爽,但是面对复杂的json串,不能很好的面对它的变化,变化点在于,JToken[][][][][][][][][],中括号的个数未知,我不知道哪天出来的json串会有几个[],如果使用到解析json串的地方很多,这个中括号的数量会非常多,看着非常恶心。。。。。。。。当然也许Newtonsoft有解决办法,但是我没摸索出来。

    1.Json串的多样性

    json串是由Web服务端安排的,各种命名,各种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串解析。

    然后再使用

    三.单例模式

    使用单例模式来创建管理职责链,使用单例管理职责链的目的是职责链只负责处理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     }
  • 相关阅读:
    插入数据失败提示: Setting autocommit to false on JDBC Connection 自动提交失败
    MyBatis XML配置properties
    mybatis 测试输出SQL语句到控制台配置
    原创:mysql5 还原至mysql 8.0.11数据库链接配置提示错误(修改内容有三处
    idea 快捷键汇总
    maven依赖配置和依赖范围
    pom.xml 配置 收藏
    单词的提取
    UVA10815 安迪的第一个字典 Andy's First Dictionary
    UVA11054 Gergovia的酒交易 Wine trading in Gergovia
  • 原文地址:https://www.cnblogs.com/07lyt/p/3991614.html
Copyright © 2011-2022 走看看