Head first设计模式
使用NeatUpload控件实现ASP.NET大文件上传
一般10M以下的文件上传通过设置Web.Config,再用VS自带的FileUpload控件就可以了,但是如果要上传100M甚至1G的文件就不能这样上传了。NeatUpload是一款为数不多的开源、免费的文件上传控件,不仅支持大文件上传,而且还显示上传进度。下面我们来介绍一下NeatUpload控件的使用方法。
一、下载NeatUpload并解压在任意位置
http://neatupload.codeplex.com/releases/view/59339,可以下载到最新的NeatUpload,目前最新版本应该是NeatUploadBinaries-1-3-26,解压后可以得到如下文件:
二、安装配置NeatUpload控件(.Net Framework2.0环境)
1. 将上述bin/中Brettle.Web.NeatUpload.dll添加到%windir%\assembly中:
2. 将上述bin/中Brettle.Web.NeatUpload.dll添加到项目或网站的引用中,观察Web.config文件会发现自动增加了如下配置:
1 <compilation debug="false">
2 <assemblies>
3 <add assembly="Brettle.Web.NeatUpload, Version=1.3.4034.20191, Culture=neutral, PublicKeyToken=DD134EA1C3727369"/>
4 </assemblies>
5 </compilation>
3. 在工具箱上添加项,可以得到7个工具:
我们主要使用InputFile和ProgressBar这两个控件。
4. 在Web.config的system.web节加入如下配置,
1 <httpModules>
2 <add name="UploadHttpModule" type="Brettle.Web.NeatUpload.UploadHttpModule, Brettle.Web.NeatUpload" />
3 </httpModules>
至此,NeatUpload的安装和配置工作完成。
三、使用NeatUpload控件
1. 前台代码

1 <body>
2 <form id="form1" runat="server">
3 <div>
4 <Upload:InputFile ID="AttachFile" runat="server"/>
5 <Upload:ProgressBar ID="ProgressBar1" runat='server'>
6 </Upload:ProgressBar>
7 </div>
8 <div>
9 <asp:Button ID="btnSave" runat="server" Text="保存" OnClick="btnSave_Click" />
10 </div>
11 </form>
12 </body>

2. 后台代码:

1 protected void btnSave_Click(object sender, EventArgs e)
2 {
3 if (AttachFile.HasFile)
4 {
5 string FileName = this.AttachFile.FileName;//获取上传文件的文件名,包括后缀
6 string ExtenName = System.IO.Path.GetExtension(FileName);//获取扩展名
7 string SaveFileName = System.IO.Path.Combine(
8 System.Web.HttpContext.Current.Request.MapPath("UpLoads/"),
9 DateTime.Now.ToString("yyyyMMddhhmm") + ExtenName);//合并两个路径为上传到服务器上的全路径
10 AttachFile.MoveTo(SaveFileName, Brettle.Web.NeatUpload.MoveToOptions.Overwrite);
11 string url = "UpLoads/" + DateTime.Now.ToString("yyyyMMddhhmmss") + ExtenName; //文件保存的路径
12 float FileSize = (float)System.Math.Round((float)AttachFile.ContentLength / 1024000, 1); //获取文件大小并保留小数点后一位,单位是M
13 }
14 }

3. 最终效果:
四、实例使用环境
1. 使用环境VS2012+.Net Framework2.0,如果是在.Net Framework 3.5及其以上版本使用安装和配置会更简单。
五、 常见问题
1.
解决方法是在system.webServer节中加入以下内容,让服务器允许的最大请求量增加,如下设置的是1G:
1 <security>
2 <requestFiltering>
3 <requestLimits maxAllowedContentLength="1073741824"/>
4 </requestFiltering>
5 </security>
2.
解决方法是在system.webServer节中加入以下内容,以适应在托管管道模式下运行应用程序:
1 <modules>
2 <add name="UploadHttpModule" type="Brettle.Web.NeatUpload.UploadHttpModule, Brettle.Web.NeatUpload" />
3 </modules>
工厂模式——(Head first设计模式4)
所谓工厂,肯定是和生产有关。工厂模式主要包括工厂方法模式和抽象工厂模式,有些人把简单工厂也作为一种模式,在本文我分别讨论简单工厂模式,工厂方法模式,抽象工厂模式。这些模式中同样也和生产有关。接下来,我们来看看各种工厂的特点。
简单工厂模式
上面说了只是有些人把简单工厂看做是设计模式,其实是一种编程习惯,无论是否是设计模式,本文将先看看其用法,然后简单给出其类图,最后说出其特点。
本节将面对多种比萨,先看看当顾客需要一个比萨时的过程:
1.根据类型,制作一个比萨形状。2.然后进行烘烤3.切4.打包
如果不熟悉的话,完全可以把其想想成面包的做法。
当顾客根据自己的需求要一个比萨时,用代码模拟这个过程如下:
public class Pizza
{
public void bake() { }
public void cut() { }
public void box() { }
}
public class CheesePizza:Pizza
{
public CheesePizza()
{ }
}
public class GreekPizza : Pizza
{
public GreekPizza(){}
}
public class PepperoniPizza:Pizza
{
public PepperoniPizza() { }
}
public class Store
{
public Pizza OrderPizza(string type)
{
Pizza pizza = null;
if (type=="Cheese")
{
pizza = new CheesePizza();
}
else if (type=="Greek")
{
pizza = new GreekPizza();
}
else if (type == "Pepperoni")
{
pizza = new PepperoniPizza();
}
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
以上的设计方法和我们的以前提到的过的原则(找出经常变化的部分,抽象成类),很明显在if else 的地方发生经常性变化。
接下来就把if else 放到一个类中。修改后的代码
public class Store
{
public Pizza OrderPizza(string type)
{
Pizza pizza = null;
//if (type=="Cheese")
//{
// pizza = new CheesePizza();
//}
//else if (type=="Greek")
//{
// pizza = new GreekPizza();
//}
//else if (type == "Pepperoni")
//{
// pizza = new PepperoniPizza();
//}
SimpleFactory factory = new SimpleFactory();
pizza =factory.CreatePizza(type);
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
public class SimpleFactory
{
public Pizza CreatePizza(string type)
{
Pizza pizza = null;
if (type == "Cheese")
{
pizza = new CheesePizza();
}
else if (type == "Greek")
{
pizza = new GreekPizza();
}
else if (type == "Pepperoni")
{
pizza = new PepperoniPizza();
}
return pizza;
}
}
这样的话,就可以遵循了把变化的部分抽象成一个类。下次需要变化,只需要对变化的类的部分做修改即可。下面给出其UML图。

简单工厂的目的,主要负责实现生产对象的细节,根据订单来生产。每一个商店有对应着自己的工厂。在此,可以将OrderPizza是工厂的一个客户,当然还可以是其他类似的方法,比如PizzaShopMenu也可以是工厂的客户。客户就是为了获取工厂生成的对象。前者是为了卖给people,后者是为了使用Pizza类获取其描述和价格等。这样遵循了找出变化的部分,将其封装到一个类中的原则,从而到达了复用的目的。
简单工厂之所以简单是因为它只根据需要,来生产出来指定的Pizza。特点:所有的产品都由一个工厂来生产。
接下来我们来看看工厂方法的实现。
工厂方法模式
如果是有多个商店,各个商店对于相同名字的pizza都有自己的生成方法。而且,除了生成方法不一样,其他的烘烤,切,打包,都是使用一样的步骤。下面就该我们的工厂方法模式出厂了。
由于生产pizza的方法决定于各个商店,不妨假设有两个商店。其公共的基类,应该有一个抽象的生产方法,具体的生产方法决定于商店。其UML类图如下:

上面的PizzaStore是一个抽象类,该类具有一个CreatePizza的抽象方法,真正实现的是具体的商店。
除了有多种商店,每个商店有多种Pizza类,而且是Pizza名是相同的,只是地区不一样,下面Pizza类的命名方式为:地区+Pizza名,其UML类图为:

商店和pizza的大致联系如下图:

在工厂方法中,使用了一个重要的原则:
原则五:依赖倒置:依赖于抽象,不要依赖于具体类
如果没有使用上述原则,而是直接让店铺依赖于每个Pizza类。

如果Pizza的实现变化了,就必须改变PizzaStore。每增加一个Pizza都会增加一个依赖。如果使用工厂方法设计模式的话,其依赖于抽象,不依赖与具体类。我们可以抽象出一个Pizza类,让所有商店以及所有的Pizza类来依赖它。这里涉及到一个依赖倒置的另一种解释,高层组件和底层组件都依赖于抽象。而不依赖与具体的实现,高层组件是有底层组件的方法构建 而成的。PizzaStore是由Pizza的Bake,Cut,Box方法构建。那么根据这个原则其大致图为:

这样的设计方法,对于任何添加新的Pizza种类,不会影响到PizzaStore。从而实现了松耦合的效果。
工厂方法和简单工厂设计模式的区别:简单工厂设计模式,只有一个工厂,每次增加新类,都需要修改SimpleFactory的代码,不能对工厂的创建方式进行分类管理,全部都由一个工厂制作。工厂方法,可以对工厂进行扩展,也就是可以对Pizza类分类管理,可以由不同的工厂去创建,更加灵活。
这个好比,简单工厂只有可以看成商店只有一家供应商,需要什么样子的产品,直接给工厂说,工厂如果没有的话要不然制造出来对象,要不然告诉供应商,我不能创建。工厂方法可以看成商店有多个供应商,需要的产品,可以有多重选择。
下面给出工厂方法的测试代码:
PizzaStore store = new NYPizzaStore();
store.OrderPizza("Greek");
store.OrderPizza("Cheese");
store = new ChicagoPizzaStore();
store.OrderPizza("Greek");
store.OrderPizza("Cheese");
抽象工厂模式
抽象工厂模式的定义:抽象工厂模式提供了一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体的类。
定义感觉还真有些抽象,下面就把他易于理解化。
抽象工厂允许客户使用抽象的接口来创建一组相关的产品,而不需要知道实际的具体产品是什么。这样客户就从具体的产品中被解耦了。
下面就来看个关于南北方饮食的差异:
主食分别是北方风味和南方风味。无论是南方味道还是北方味道,其都包括主食和调料:北方主要是以面食和辣椒为主,南方主要是以大米和糖为主。
下面就使用抽象工厂来抽象两个接口,分别是主食和调料,对应还有两种风味。

接下来是调料和事务的对应实现:

接下来看看其联系

在上图中,AbstractFactory接口定义了两个方法来分别获得调料和主食。下面的南北风味是可以看出其具体实现。
这样就可以在前台查看风味的主食和调料就不用关心具体的实现。直接调用其Create方法就行了。
测试代码:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("南方风味:");
AbstractFactory factory = new SouthFood();
Food food = factory.CreateFood();
Console.WriteLine(food.Name);
Condiment condiment = factory.CreateCondiment();
Console.WriteLine(condiment.Name);
Console.WriteLine("北方风味:");
AbstractFactory factory2 = new NouthFood();
Food food2 = factory2.CreateFood();
Console.WriteLine(food2.Name);
Condiment condiment2 = factory2.CreateCondiment();
Console.WriteLine(condiment2.Name);
Console.ReadKey();
}
}
从该实例,可以看出抽象工厂是定义了多类产品。工厂方法是一个对象有多种做法,所以在抽象工厂中可以使用多个工厂方法。如果理解了工厂方法,那么抽象工厂应该更好理解些。
抽象工厂是单个接口定义了多个方法,所以具体的工厂肯定都要实现创建方法。
源码
设计模式
Head first设计模式的更多相关文章
- MVVM设计模式和WPF中的实现(四)事件绑定
MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...
- java EE设计模式简介
1.何为设计模式 设计模式提供了对常见应用设计问题的解决方案.在面向对象的编程中,设计模式通常在解决与对象创建和交互相关的问题,而非整体软件架构所面对的大规模问题,它们以样板代码的形式提供了通用的解决 ...
- 计算机程序的思维逻辑 (54) - 剖析Collections - 设计模式
上节我们提到,类Collections中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了第一类,本节我们介绍第二类. 第二类方法大概可以分为两组: 接受其他 ...
- 《JavaScript设计模式 张》整理
最近在研读另外一本关于设计模式的书<JavaScript设计模式>,这本书中描述了更多的设计模式. 一.创建型设计模式 包括简单工厂.工厂方法.抽象工厂.建造者.原型和单例模式. 1)简单 ...
- 《JavaScript设计模式与开发实践》整理
最近在研读一本书<JavaScript设计模式与开发实践>,进阶用的. 一.高阶函数 高阶函数是指至少满足下列条件之一的函数. 1. 函数可以作为参数被传递. 2. 函数可以作为返回值输出 ...
- 设计模式之行为类模式大PK
行为类模式大PK 行为类模式包括责任链模式.命令模式.解释器模式.迭代器模式.中介者模式.备忘录模式.观察者模式.状态模式.策略 ...
- .NET设计模式访问者模式
一.访问者模式的定义: 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 二.访问者模式的结构和角色: 1.Visitor 抽象访问者角色,为该 ...
- Java开发中的23种设计模式详解
[放弃了原文访问者模式的Demo,自己写了一个新使用场景的Demo,加上了自己的理解] [源码地址:https://github.com/leon66666/DesignPattern] 一.设计模式 ...
- java 设计模式
目录: 设计模式六大原则(1):单一职责原则 设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计 ...
- 设计模式之单例模式(Singleton)
设计模式之单例模式(Singleton) 设计模式是前辈的一些经验总结之后的精髓,学习设计模式可以针对不同的问题给出更加优雅的解答 单例模式可分为俩种:懒汉模式和饿汉模式.俩种模式分别有不同的优势和缺 ...
随机推荐
- 重写ArcGIS的TiledMapServiceLayer呼叫世界地图图块
require(["esri/layers/TiledMapServiceLayer"], function () { dojo.declare("com.Str ...
- C#中反射的概念及其使用(转)
提纲:1. 什么是反射2. 命名空间与装配件的关系3. 运行期得到类型信息有什么用4. 如何使用反射获取类型5. 如何根据类型来动态创建对象6. 如何获取方法以及动态调用方法7. 动态创建委托 1.什 ...
- BIP Requests Are Failing With Error "OPP Error Oracle.apps.xdo.XDOException: Error Creating Lock Fil
In this Document Symptoms Cause _afrLoop=975833031487795&id=1512691.1&displayIndex=1&a ...
- android studio 添加到项目库中的项目
工程-对-new module-Android Library-module name和package name 它应该在同一个库被引入. 然后在该文件夹replace新的library 在gradl ...
- 给已经编译运行的Apache增加mod_proxy模块的配置方法
在Linux系统下,需要给已经编译运行的Apache增加mod_proxy模块,可以按照如下方法配置. 具体配置步骤如下: 1. 首先定位到Apache源码的 proxy目录 # cd /root/s ...
- PHP时间戳与时间相互转换(精确到毫秒)
原文:PHP时间戳与时间相互转换(精确到毫秒) /** 获取当前时间戳,精确到毫秒 */ function microtime_float(){ list($usec, $sec) = explo ...
- Cocos2d-x3.0 TestCPP文件夹的注意事项
1.不多说了,重力加速度. 2.ActionMangerTest:此Test它是由导演来展示,以获得集体诉讼经理ActionManager类别,操作控制节点. ①CrashTest:破坏demo,毁. ...
- Swift 制作一个新闻通知中心插件1
使用 Swift 制作一个新闻通知中心插件(1) 随着 iOS 8 的发布,苹果为开发者们开放了很多新的 API,而在这些开放的接口中 通知中心插件 无疑是最显眼的一个.通知中心就不用过多介绍了,相信 ...
- 《MonkeyRunner原理剖析》第九章-MonkeyImage实现原理 - 第一节 - 关键类作用及关系
MonkeyRunner框架暴露了几个类的大量的API出去给用户编写脚本时候使用,其中最主要的三个就是: MonkeyDevice目标设备操作类,HierarchyViewer窗口界面对象操作类以及M ...
- xfire集成spring构建webservice
前言:xfire.spring都是比较流行的技术,这里就不再赘述他们各自的优点:本文着重介绍xfire和spring的整合,不会做太深入的探究. 服务端 1. web.xml配置 spring配置部分 ...