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     }

今天就到这。。。感觉还是太菜。。

时间: 2024-10-18 22:12:01

DoubanFm之设计模式(一)的相关文章

Java设计模式——创建型模式之单例模式

一.概述 作为第一个出场的设计模式,有必要先介绍一下设计模式(引用自百度百科): 设计模式(Design Pattern)是一套被反复使用.多数人知晓的.经过分类的.代码设计经验的总结. 使用设计模式的目的:为了代码可重用性.让代码更容易被他人理解.保证代码可靠性. 设计模式使代码编写真正工程化:设计模式是软件工程的基石脉络,如同大厦的结构一样. 设计模式概念的介绍,参见:http://blog.jobbole.com/101076/ 其中涉及的设计原则的概念,参见随笔:http://www.c

10大APP界面框架设计模式详解

随着移动互联网的发展,移动app已经成为了每个互联网公司的标配了,那作为产品经理,我们如何设计出更加符合用户体验的app产品呢?今天和大家分享的就是10中最常见的app界面光甲设计模式,一起来看看吧. 1.标签导航 标签导航是十大界面框架设计里最常用的界面框架设计,也是被业界之内公认的一种普遍使用的页面框架设计.那么这种页面框架设计在作业方面对一个用户来说也是最常见的一种页面框架设计,比如说微博.微信.手机百度.支付宝.淘宝,这些我们所谓的超级APP都是运用的标签导航,无一例外.从这个角度也可以

[js高手之路]设计模式系列课程-组合模式+寄生组合继承实战新闻列表

所谓组合模式,就是把一堆结构分解出来,组成在一起,现实中很多这样的例子,如: 1.肯德基套餐就是一种组合模式, 比如鸡腿堡套餐,一般是是由一个鸡腿堡,一包薯条,一杯可乐等组成的 2.组装的台式机同理,由主板,电源,内存条,显卡, 机箱,显示器,外设等组成的 把一个成型的产品组成部件,分成一个个独立的部件,这种方式可以做出很多灵活的产品,这就是组合模式的优势 比如:家用台式机电脑,要求配置比较低, 这个时候只需要主板+电源+内存条+机箱+显示器+外设就可以了,不需要配置独立显卡 鸡腿堡+鸡翅+紫薯

Happy 设计模式之适配器模式(JAVA)

设计模式-适配器模式 适配器模式定义 适配器模式,将一个类的的接口转换成客户或者产品希望的接口形式,就是原本不兼容或者甚至不相干的接口不能一起工作的接口一起工作,完成需求或者客户的需求. 适配器模式的使用场景 1.当你使用一个已经存在的类,而他的接口不符合你的需求. 2.你想要创建一个复用的类,该类可以与其相关的类或者不可见的类协同工作. 适配器角色 Target:目标接口 TargetImpl:目标实现类 Adapter:适配器 Adaptee:被适配者 代码解析: package com.d

设计模式 2/23 工厂模式

工厂模式是最常用的设计模式之一,用好了,代码优雅,可维护性高,对系统设计会上一个台阶 为什么这么说,因为工厂模式可以牵扯出抽象工厂模式,也有大家都会聊到的简单工厂模式 我们要了解一点,23中设计模式中,不包含简单工厂模式,之所以大家会去聊这个,四个字,渐进明细 通过对简单工厂模式的了解,我们引入工厂这个词,不然一个写代码的,天天给他讲工厂,工厂,工厂,西厂,东厂,会晕 同时,通过逐步的深入,从简单工厂,到工厂模式,再到抽象工厂,渐进明细的过程,逐步深入的理解,比较优劣,择优而为我们所用. 试想我

Java设计模式学习笔记,一:单例模式

开始学习Java的设计模式,因为做了很多年C语言,所以语言基础的学习很快,但是面向过程向面向对象的编程思想的转变还是需要耗费很多的代码量的.所有希望通过设计模式的学习,能更深入的学习. 把学习过程中的笔记,记录下来,只记干货. 第一部分:单例模式的内容 单例模式:类只能有一个实例. 类的特点:1.私有构造器:2.内部构造实例对象:3.对外提供获取唯一实例的public方法. 常见的单例模式实现有五种形式: 1.饿汉式. 2.懒汉式. 3.双重检查锁式. 4.静态内部类式. 5.枚举式. 以下分别

设计模式之单列模式

设计模式之单列模式 1,何为单列模式? 即singleton 在某个类采用了单列模式之后  其只能有一个实列对象 ,并且这个实列对象只能有内部自己创建并提供给外部的调用. 2.实现单列模式的方法 分为 :饿汉式 ,懒汉式 下面为饿汉式实现代码: public calss Singleton1{ //将构造函数私有化 防止外部通过new来创建对象 private Singleton1(){ } //创建一个私有静态变量并直接初始化 类加载的时候直接创建对象 private static Singl

设计模式之原型模式(Prototype)

1.初识原型模式 大家都知道连锁机构是现在灰常流行的商业模式,比如咖啡之翼,那么假设咖啡之翼要在长春新建立一个分店,所经营的产品和以前在其他的城市已经存在的店经营的产品差不多,那么面向对象开发的角度怎么解决这个问题呢?难道要重新的实例化一个咖啡之翼的店??这显然不太好吧,咖啡之翼里面经营的产品(假设是属性吧)都需要重新写,这就是在做大量的重复工作啊,这显然是不符合OO开发思想的.遇到这样的情况,并不是重新建立一个类来解决这样的问题,而是通过设计模式中的"原型模式"来解决这种问题.是这种

对设计模式的总结之简单工厂与策略模式

前言 面向对象编程追求的本质-提高扩展性.可维护性.灵活性和复用性.合理利用面向对象6个原则,能够很好的达到要求.如何利用好就是至关重要的了,前人总结了23+个设计模式能够让初学者更容易学到其中的精髓,本文就说说我对本人对简单工厂模式.策略模式的见解. 简单工厂模式与策略模式 简单工厂模式 工作中,常常遇到需要做一个功能(鸭子),这个功能中含有可控个数的子操作功能(鸭子叫,鸭子跑,鸭子飞),而且子功能在不同的情况下处理方式又不相同(成年鸭子/小鸭子叫,成年鸭子/小鸭子跑,成年鸭子/小鸭子飞).我