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

第二版用了比较多的依赖注入,熟悉了Messenger,过后越写越大,感觉不对,赶快打住。。现在开始好好思考各模块了。

在Http请求方面,在知道了Restful后还没有机会使用它,感觉Restful应该还不错,不过我还是为我的Http请求使用了下面的设计模式

一.工厂方法

1.抽象产品

UML有空再画,先上代码,

使用Rx建立抽象的Get类产品,如下:

 public  abstract class HttpGetMethodBase<T>
{
public virtual IObservable<T> Get(string Url)//设置虚拟方法是为了多态 但是这里不用设置应该也可以
{
//多态既是为了用子类的方法
//其实我这里不需要用子类的方法
//写了应该也可以
//只要注意子类的Override
var func = Observable.FromAsyncPattern<HttpWebRequest, T>(Webrequest, WebResponse);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(Url);
return func(request);
}
private IAsyncResult Webrequest(HttpWebRequest request, AsyncCallback callbcak, object ob)
{
return request.BeginGetResponse(callbcak, request);
} //发的请求用的是父类的get,WebResponse用的是子类的
protected abstract T WebResponse(IAsyncResult result);
}

作为抽象的产品,有些方法可以共享,比如Get方法。要重写的是WebResponse

2.具体产品

(1)返回stream的产品

   public class HttpGetStream : HttpGetMethodBase<Stream>
{
protected override Stream WebResponse(IAsyncResult result)
{
try
{
var request = result.AsyncState as HttpWebRequest;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
#region ignore
if (response.Cookies != null)
{
foreach (Cookie cookie in response.Cookies)
{
Debug.WriteLine(cookie.Value);
}
}
Debug.WriteLine(response.ContentType);
Debug.WriteLine(response.StatusDescription);
if (response.Headers["Set-Cookie"] != null)
{
//setting may write
Debug.WriteLine(response.Headers["Set-Cookie"]);
}
#endregion
return response.GetResponseStream();
}
catch
{
Debug.WriteLine("WEBERROR");
return null;
}
}
}

(2)返回string的产品

   public class HttpGetString : HttpGetMethodBase<string>
{
protected override string WebResponse(IAsyncResult result)
{
try
{
var request = result.AsyncState as HttpWebRequest;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
#region ignore
if (response.Cookies != null)
{
foreach (Cookie cookie in response.Cookies)
{
Debug.WriteLine(cookie.Value);
}
}
Debug.WriteLine(response.ContentType);
Debug.WriteLine(response.StatusDescription);
if (response.Headers["Set-Cookie"] != null)
{
//setting may write
Debug.WriteLine(response.Headers["Set-Cookie"]);
}
#endregion
Stream stream = response.GetResponseStream();
using (StreamReader sr = new StreamReader(stream))
{
return sr.ReadToEnd();
}
}
catch
{
Debug.WriteLine("WEBERROR");
return null;
}
}
}

(3)返回位图的产品

   public class HttpGetBitmapImage : HttpGetMethodBase<BitmapImage>
{
protected override BitmapImage WebResponse(IAsyncResult result)
{
try
{
var request = result.AsyncState as HttpWebRequest;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
#region ignore
if (response.Cookies != null)
{
foreach (Cookie cookie in response.Cookies)
{
Debug.WriteLine(cookie.Value);
}
}
Debug.WriteLine(response.ContentType);
Debug.WriteLine(response.StatusDescription);
if (response.Headers["Set-Cookie"] != null)
{
//setting may write
Debug.WriteLine(response.Headers["Set-Cookie"]);
}
#endregion
Stream stream = response.GetResponseStream();
BitmapImage bitmapimage = new BitmapImage();
bitmapimage.SetSource(stream);
return bitmapimage;
}
catch
{
Debug.WriteLine("WEBERROR");
return null;
}
}
}

现在主要有三种产品,如果以后有返回音频的产品,就照搬就好了,这样便于扩展。

3.接口工厂(不叫抽象工厂是怕跟抽象工厂模式冲突)

(1)用于创建对象(产品)的接口

 interface IHttpGet<T>
{
HttpGetMethodBase<T> CreateHttpRequest();
}

(2)具体的工厂

具体工厂都用来创建具体的产品

1.string(get)工厂

  public class StringHttpFactory:IHttpGet<string>
{
public HttpGetMethodBase<string> CreateHttpRequest()
{
return new HttpGetString();
}
}

2.stream(get)工厂

   public class StreamHttpFactory : IHttpGet<Stream>
{ public HttpGetMethodBase<Stream> CreateHttpRequest()
{
return new HttpGetStream();
}
}

3.位图工厂

 public class BitmapImageHttpFactory : IHttpGet<BitmapImage>
{
public HttpGetMethodBase<BitmapImage> CreateHttpRequest()
{
return new HttpGetBitmapImage();
}
}

客户端调用:

客户端调用还是得知道具体的工厂型号,所以这里我打个问号,先看看代码吧

   IHttpGet<string> factory = new StringHttpFactory();//string 工厂
factory.CreateHttpRequest().Get("http://douban.fm/j/mine/playlist?from=mainsite&channel=0&kbps=128&type=n").Subscribe(
(result) =>
{
});

代码new了一个具体的工厂,这里并没有达到真正的解耦,所以我考虑看能不能以后做

1。配置文件反射处理

2.依赖注入。

//to be continued................

二.职责链

先看看背景。

虽然用Newtonsoft的json库很爽,但是面对复杂的json串,不能很好的面对它的变化,变化点在于,JToken[][][][][][][][][],中括号的个数未知,我不知道哪天出来的json串会有几个[],如果使用到解析json串的地方很多,这个中括号的数量会非常多,看着非常恶心。。。。。。。。当然也许Newtonsoft有解决办法,但是我没摸索出来。

1.Json串的多样性

json串是由Web服务端安排的,各种命名,各种key/vaule,客户端很难应对这种变。

用职责链的效果是:客户端只用发出获得的json字符串,就可以获得与之对应的类,至于json串怎么被处理的,客户端不知道

上代码

   public abstract class RequestorBase<T>
{
protected RequestorBase<T> Successor;
internal void SetSucessor(RequestorBase<T> suc)
{
Successor = suc;
}
public abstract T ProcessRequest(string json);//抽象不依赖于具体,抽象依赖于抽象
} public class Requestor1<T> : RequestorBase<T>
{
public override T ProcessRequest(string json)
{
try
{
return JsonConvert.DeserializeObject<T>(JToken.Parse(json)["song"].ToString());
}
catch
{
Debug.WriteLine("这个是在职责链中的该有的异常");
return Successor.ProcessRequest(json);
}
}
}
public class Requestor2<T> : RequestorBase<T>
{
public override T ProcessRequest(string json)
{
try
{
return JsonConvert.DeserializeObject<T>(JToken.Parse(json)["song"][].ToString());
}
catch
{
Debug.WriteLine("这个是在职责链中的该有的异常");
return Successor.ProcessRequest(json);
}
}
}
public class Requestor3<T> : RequestorBase<T>
{
public override T ProcessRequest(string json)
{
Debug.WriteLine("在职责链中没有能找到处理请求的方法,返回Default");
return default(T);
//NO Chain 继续下去了
}
}

不同的职责人作不同的json串解析。

然后再使用

三.单例模式

使用单例模式来创建管理职责链,使用单例管理职责链的目的是职责链只负责处理json串,他们都是无状态的,所有把他们的方法装入内存就可以了。

   public class ManagerResponsibilityChain<T>
{
static private RequestorBase<T> _startrequestor;
static public RequestorBase<T> Instance_Startrequestor
{
get
{
if (_startrequestor == null)
{
Inital();
}
return _startrequestor;
}
}
private ManagerResponsibilityChain()
{ }
static private void Inital()
{
_startrequestor = new Requestor1<T>();
var secondrequestor = new Requestor2<T>();
var thridrequestor = new Requestor3<T>();
_startrequestor.SetSucessor(secondrequestor);
secondrequestor.SetSucessor(thridrequestor);//requestor3 is the end
}
}

今天就到这。

后面再来追加一下:

对于上面的职责链,要想增加职责者,难免会忘记增加的过程,要插入在倒数第二个地方,再重新设置后两个的职责链

    public class ManagerResponsibilityChain<T>
{
static private RequestorBase<T> _startrequestor;
static public RequestorBase<T> Instance_Startrequestor
{
get
{
if (_startrequestor == null)
{
Inital();
}
return _startrequestor;
}
}
private ManagerResponsibilityChain()
{ }
static public List<RequestorBase<T>> RequestList=new List<RequestorBase<T>>();
static private void InsertARequestor(RequestorBase<T> InsertItem)
{
RequestList.Insert(RequestList.Count - , InsertItem);
InsertItem.SetSucessor(RequestList[RequestList.Count - ]);
RequestList[RequestList.Count - ].SetSucessor(InsertItem); } static private void Inital()
{ _startrequestor = new Requestor1<T>();
var secondrequestor = new Requestor2<T>();
var thridrequestor = new Requestor3<T>();
RequestList.Add(_startrequestor);
RequestList.Add(secondrequestor);
RequestList.Add(thridrequestor);
_startrequestor.SetSucessor(secondrequestor);
secondrequestor.SetSucessor(thridrequestor);//requestor3 is the end InsertARequestor(new Requestor4<T>());
InsertARequestor(new Requestor5<T>());
InsertARequestor(new Requestor6<T>());
} }

或者是

   public class ManagerResponsibilityChain<T>
{
static private RequestorBase<T> _startrequestor;
static public RequestorBase<T> Instance_Startrequestor
{
get
{
if (_startrequestor == null)
{
Inital();
}
return _startrequestor;
}
}
private ManagerResponsibilityChain()
{ } static private void InsertARequestor(RequestorBase<T> InsertItem, List<RequestorBase<T>> RequestList)
{
RequestList.Insert(RequestList.Count - , InsertItem);
InsertItem.SetSucessor(RequestList[RequestList.Count - ]);
RequestList[RequestList.Count - ].SetSucessor(InsertItem); } static private void Inital()
{
List<RequestorBase<T>> RequestList = new List<RequestorBase<T>>();
_startrequestor = new Requestor1<T>();
var secondrequestor = new Requestor2<T>();
var thridrequestor = new Requestor3<T>();
RequestList.Add(_startrequestor);
RequestList.Add(secondrequestor);
RequestList.Add(thridrequestor);
_startrequestor.SetSucessor(secondrequestor);
secondrequestor.SetSucessor(thridrequestor);//requestor3 is the end InsertARequestor(new Requestor4<T>(), RequestList);
InsertARequestor(new Requestor5<T>(), RequestList);
InsertARequestor(new Requestor6<T>(), RequestList);
} }

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

  1. MVVM设计模式和WPF中的实现(四)事件绑定

    MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  2. java EE设计模式简介

    1.何为设计模式 设计模式提供了对常见应用设计问题的解决方案.在面向对象的编程中,设计模式通常在解决与对象创建和交互相关的问题,而非整体软件架构所面对的大规模问题,它们以样板代码的形式提供了通用的解决 ...

  3. 计算机程序的思维逻辑 (54) - 剖析Collections - 设计模式

    上节我们提到,类Collections中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了第一类,本节我们介绍第二类. 第二类方法大概可以分为两组: 接受其他 ...

  4. 《JavaScript设计模式 张》整理

    最近在研读另外一本关于设计模式的书<JavaScript设计模式>,这本书中描述了更多的设计模式. 一.创建型设计模式 包括简单工厂.工厂方法.抽象工厂.建造者.原型和单例模式. 1)简单 ...

  5. 《JavaScript设计模式与开发实践》整理

    最近在研读一本书<JavaScript设计模式与开发实践>,进阶用的. 一.高阶函数 高阶函数是指至少满足下列条件之一的函数. 1. 函数可以作为参数被传递. 2. 函数可以作为返回值输出 ...

  6. 设计模式之行为类模式大PK

                                        行为类模式大PK 行为类模式包括责任链模式.命令模式.解释器模式.迭代器模式.中介者模式.备忘录模式.观察者模式.状态模式.策略 ...

  7. .NET设计模式访问者模式

    一.访问者模式的定义: 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 二.访问者模式的结构和角色: 1.Visitor 抽象访问者角色,为该 ...

  8. Java开发中的23种设计模式详解

    [放弃了原文访问者模式的Demo,自己写了一个新使用场景的Demo,加上了自己的理解] [源码地址:https://github.com/leon66666/DesignPattern] 一.设计模式 ...

  9. java 设计模式

    目录: 设计模式六大原则(1):单一职责原则 设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计 ...

随机推荐

  1. Runtime机制之结构体及操作函数

    一.动态语言 Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理.这种动态语言的优势在于:具有灵活性,比如:消息转发,方法交换等.它有一个运行时系统Ob ...

  2. 【最后一篇API译文】Android开发-API指南- Contacts Provider

    Contacts Provider 今年加入了某字幕组,加之杂事颇多,许久未添新文了,惭愧之极. 在听闻 Google 即将重返中国后,近日忽又发现官方网站正在放出 API 中文版,比如本文.当然不是 ...

  3. dll 学习(一)

    DLL(Dynamic Link Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用的变量.函数或类.在仓库的发展史上经历了"无库-静态链接库-动态链接库 ...

  4. redis错误总结

    1.同步错误.不停重试一直不成功 Full resync from master: e51165e2868c541e28134a287f9bfe36372bae34:80575961684 MASTE ...

  5. Android多线程异步处理:AsyncTask 的实现原理

    AsyncTask主要用来更新UI线程,比较耗时的操作可以在AsyncTask中使用. AsyncTask是个抽象类,使用时需要继承这个类,然后调用execute()方法.注意继承时需要设定三个泛型P ...

  6. Android创建自定义dialog方法详解-样式去掉阴影效果

    在自定义组件时,从已有组件源码中会很大收获.就拿progressDialog来说     间接父类是dialog,想了解dialog继承结构可以去百度,或者    从构造器来说ProgressDial ...

  7. C++中rapidxml用法及例子

    rapidxml是一个快速的xml库,比tinyxml快了50-100倍.本文给出创建.读取.写入xml的源码. 由于新浪博客不支持文本文件上传,在使用下面代码需要先下载 rapidxml,关于这个库 ...

  8. SQLServer 窗口函数

    一.窗口函数的作用 窗口函数是对一组值进行操作,不需要使用GROUP BY 子句对数据进行分组,还能够在同一行中同时返回基础行的列和聚合列.窗口函数,基础列和聚合列的查询都非常简单. 二.语法格式 窗 ...

  9. jsp-status 404错误的解决方法汇总

    接下来的解决方法实在一下情况下进行的: 1.tomcat配置是对的,能打开tomcat的主页(网址:http://localhost:8080/),如图, 但是在输入具体网址的时候,例如:http:/ ...

  10. 移动端rem自适应布局关键代码

    function resi() { var html = document.querySelector("html"); var wW = document.body.client ...