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>
 
 
分类: ASP.NET相关

工厂模式——(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图。

image

简单工厂的目的,主要负责实现生产对象的细节,根据订单来生产。每一个商店有对应着自己的工厂。在此,可以将OrderPizza是工厂的一个客户,当然还可以是其他类似的方法,比如PizzaShopMenu也可以是工厂的客户。客户就是为了获取工厂生成的对象。前者是为了卖给people,后者是为了使用Pizza类获取其描述和价格等。这样遵循了找出变化的部分,将其封装到一个类中的原则,从而到达了复用的目的。

简单工厂之所以简单是因为它只根据需要,来生产出来指定的Pizza。特点:所有的产品都由一个工厂来生产。

接下来我们来看看工厂方法的实现。

工厂方法模式

如果是有多个商店,各个商店对于相同名字的pizza都有自己的生成方法。而且,除了生成方法不一样,其他的烘烤,切,打包,都是使用一样的步骤。下面就该我们的工厂方法模式出厂了。

由于生产pizza的方法决定于各个商店,不妨假设有两个商店。其公共的基类,应该有一个抽象的生产方法,具体的生产方法决定于商店。其UML类图如下:

image

上面的PizzaStore是一个抽象类,该类具有一个CreatePizza的抽象方法,真正实现的是具体的商店。

除了有多种商店,每个商店有多种Pizza类,而且是Pizza名是相同的,只是地区不一样,下面Pizza类的命名方式为:地区+Pizza名,其UML类图为:

image

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

image

在工厂方法中,使用了一个重要的原则:

原则五:依赖倒置:依赖于抽象,不要依赖于具体类

如果没有使用上述原则,而是直接让店铺依赖于每个Pizza类。

image

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

image

这样的设计方法,对于任何添加新的Pizza种类,不会影响到PizzaStore。从而实现了松耦合的效果。

工厂方法和简单工厂设计模式的区别:简单工厂设计模式,只有一个工厂,每次增加新类,都需要修改SimpleFactory的代码,不能对工厂的创建方式进行分类管理,全部都由一个工厂制作。工厂方法,可以对工厂进行扩展,也就是可以对Pizza类分类管理,可以由不同的工厂去创建,更加灵活。

这个好比,简单工厂只有可以看成商店只有一家供应商,需要什么样子的产品,直接给工厂说,工厂如果没有的话要不然制造出来对象,要不然告诉供应商,我不能创建。工厂方法可以看成商店有多个供应商,需要的产品,可以有多重选择。

下面给出工厂方法的测试代码:

PizzaStore store = new NYPizzaStore(); 
store.OrderPizza("Greek"); 
store.OrderPizza("Cheese");

store = new ChicagoPizzaStore(); 
store.OrderPizza("Greek"); 
store.OrderPizza("Cheese");

抽象工厂模式

抽象工厂模式的定义:抽象工厂模式提供了一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体的类。

定义感觉还真有些抽象,下面就把他易于理解化。

抽象工厂允许客户使用抽象的接口来创建一组相关的产品,而不需要知道实际的具体产品是什么。这样客户就从具体的产品中被解耦了。

下面就来看个关于南北方饮食的差异:

主食分别是北方风味和南方风味。无论是南方味道还是北方味道,其都包括主食和调料:北方主要是以面食和辣椒为主,南方主要是以大米和糖为主。

下面就使用抽象工厂来抽象两个接口,分别是主食和调料,对应还有两种风味。

image

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

image

接下来看看其联系

image

在上图中,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(); 
       } 
   }

从该实例,可以看出抽象工厂是定义了多类产品。工厂方法是一个对象有多种做法,所以在抽象工厂中可以使用多个工厂方法。如果理解了工厂方法,那么抽象工厂应该更好理解些。

抽象工厂是单个接口定义了多个方法,所以具体的工厂肯定都要实现创建方法。

源码

FactoryPattern.zip

 

设计模式

 
摘要: 所谓工厂,肯定是和生产有关。工厂模式主要包括工厂方法模式和抽象工厂模式,有些人把简单工厂也作为一种模式,在本文我分别讨论简单工厂模式,工厂方法模式,抽象工厂模式。这些模式中同样也和生产有关。接下来,我们来看看各种工厂的特点。简单工厂模式上面说了只是有些人把简单工厂看做是设计模式,其实是一种编程习惯,无论是否是设计模式,本文将先看看其用法,然后简单给出其类图,最后说出其特点。本节将面对多种比萨,先看看当顾客需要一个比萨时的过程:1.根据类型,制作一个比萨形状。2.然后进行烘烤3.切4.打包如果不熟悉的话,完全可以把其想想成面包的做法。当顾客根据自己的需求要一个比萨时,用代码模拟这个过程如下:pu阅读全文
posted @ 2013-10-17 21:22 haiziguo 阅读(67) | 评论 (0) 编辑
 
摘要: 装饰者模式定义装饰者模式动态的将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。从定义来看,除了提到比继承更有弹性,其他的还是非常模糊,下面就先给出其UML类图。从UML类图可以看到装饰者基类(Decorator)主要使用了一个其基类的组合,另外装饰者分别含有自己的新特性,如ConcreteDecoratorA,有自己特有的字段,ConcreteDecoratorB有自己特有的方法。该模式设计的巧妙的地方就在于以上的特点。为什么说巧妙呢?因为装饰者都含有一个Component的引用,就好比你是老板要找c#开发的,遇到了一个不仅会c#的,还会java的你一样,这样的好处是不阅读全文
posted @ 2013-10-09 23:18 haiziguo 阅读(516) | 评论 (2) 编辑
 
摘要: 1.1观察者模式定义在给出观察者模式的定义之前,我们先来看个报纸和杂志的订阅是怎么回事:1.报社的业务就是出版报纸2.向某家报社订阅报纸,只有新报纸出版,报社才会送给你,只要你是用户,他就会一直向你发送。3.当你不向看报纸了,取消订阅,他们就不会发送报纸。4.只要报社还在运营,就会有人订阅报纸或取消报纸订阅其实这个过程就和我们的观察者模式的过程相似。所以我们可以简单的将观察者模式定义为:出版社+订阅者=观察者模式这个毕竟是简单的,下面我们给出正式的定义:观察者模式定义了对象之间的一对多依赖,当一个被依赖者改变状态时,他所有的依赖者都会收到通知并自动更新。通过出版社和正式定义应该很容易理解观察者阅读全文
posted @ 2013-10-06 15:01 haiziguo 阅读(485) | 评论 (0) 编辑
 
摘要: 一、策略模式的定义策略模式定义了算法族,分别封装起来,让它们之间可以互换替换,此模式让算法的变化独立使用算法的客户。二、使用策略模式的一个例子2.1引出问题某公司做了一套模拟鸭子的游戏:该游戏会出现各种鸭子,他们具有相似点(都会叫,会游泳,会表达自己的特征)和异同点(每种展示自己的特征是不同的方法),很容易想到使用OO技术,定义个鸭子超类,让其他的鸭子类来继承鸭子超类。由于异同点都会展示自己的特征,只是展示特征方式不同,所以在超类中特征的方法是抽象或者使用一个接口(在此就使用接口,因为每一个类都会有展示方法)。下面给出其类图。可当某一天发现了问题,问题1:如果出现了一个DuckC,展示方式和D阅读全文
posted @ 2013-09-28 21:53 haiziguo 阅读(592) | 评论 (2) 编辑
 
摘要: 一、两个设计原则:原则一:找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起。鸭子模型中展现是必须的,而且每个展现都不一样,所以可以在基类中定义一个抽象类。以便子类可以更好的重写。在鸭子模型中,飞和叫的行为是经常要发生改变的,而且是鸭子的行为,我们可以让其抽象为接口。从而为每一个类传递不同的飞和叫的行为。原则二:面向接口编程,不要面向实现编程面向接口编程的含义是:让接口作为鸭子的变量,具体的实现是一个继承接口的类。这样每个继承接口的类就可以达到了复用的效果。二、动态改变鸭子的行为时,可以使用Setter,通过C#的多态来实现。public class Duck ..阅读全文
posted @ 2013-09-15 11:27 haiziguo 阅读(16) | 评论 (0) 编辑
 
分类: 设计模式
原文地址:https://www.cnblogs.com/Leo_wl/p/3375140.html