zoukankan      html  css  js  c++  java
  • 若干设计模式学习

    在petshop4.0中也用到了几个常用的设计模式:简单工厂模式,工厂方法模式,策略模式,并附之返射与配置文件.下面就来用我自己的理解用大白话说出来.

    1.简单工厂模式.

     比如A与B一起写代码,A负责前台,B负责后台,B写了两个类:X与Y,A负责调用,那么1.A怎么知道B写了X与Y两个类呢?2.B又增加了Z 类怎么办,3.A在代码里写了n个X x = new X(), B把X类改名或重写了怎么办.为了解决这些困难,就提出了简单工厂模式,说白了,有一个基类或接口,然后n个类从它继承,再写一个类作为工厂,里面有个静 态方法负责根据转入参数的不同返回从基类或接口继承的具体对象:


    代码
     public interface IPerson  
     {  
         
    string GetName();  
     }  
       
     
    public class Kernel : IPerson  
     {  
         
    public string GetName()  
         {  
             
    return "Kernel";  
         }  
     }  
       
     
    public class Json : IPerson  
     {  
         
    public string GetName()  
         {  
             
    return "Json";  
         }  
     }  
       
     
    public class PersonFactory  
     {  
         
    public static IPerson CreateInstance(string name)  
         {  
             
    string path = ConfigurationManager.AppSettings["AssemblyName"];  
             
    string className = "";  
             
    switch (name)  
             {  
                 
    case "kernel":  
                     className 
    = ConfigurationManager.AppSettings["kernelClass"];  
                     
    break;  
                 
    default:  
                     className 
    = ConfigurationManager.AppSettings["JsonClass"];  
                     
    break;  
             }  
             
    return Assembly.Load(path).CreateInstance(className) as IPerson;  
         }  
     }  
       
     
    static void Main(string[] args)  
         {  
             IPerson p1 
    = PersonFactory.CreateInstance("kernel");  
             Console.WriteLine(p1.GetName());  
             IPerson p2 
    = PersonFactory.CreateInstance("Json");  
             Console.WriteLine(p2.GetName());  
             Console.ReadKey();  
         }


    如果有变更,现在就只需要更改工厂类就可以了,这样就在一定程度上必免了因为调用对象的变更而导致代码的重写

    2.工厂方法模式

    类不多时一般用简单工厂.如果类非常多,你就会发现这个工厂会奇大无比,这时就需要对这个工厂分解,工厂方法模式就这样提出来了.

    工厂方法模式个人认为本质上就是对工厂也工厂了一遍.先用工厂产生特定类的工厂,然后用特定类的工厂生成你所需要的具体对象.

    代码
     public interface IPerson  
     {  
         
    string GetName();  
     }  
       
     
    public class Kernel : IPerson  
     {  
         
    public string GetName()  
         {  
             
    return "Kernel";  
         }  
     }  
       
     
    public class Json : IPerson  
     {  
         
    public string GetName()  
         {  
             
    return "Json";  
         }  
     }  
       
     
    public interface ICreatePerson  
     {  
         IPerson CreateInstance();  
     }  
       
     
    public class CreateKernelFactory : ICreatePerson  
     {  
         
    public IPerson CreateInstance()  
         {  
             
    string path = ConfigurationManager.AppSettings["AssemblyName"];  
             
    string className = ConfigurationManager.AppSettings["kernelClass"];  
             
    return Assembly.Load(path).CreateInstance(className) as IPerson;  
         }  
     }  
       
     
    public class CreateJsonFactory : ICreatePerson  
     {  
         
    public IPerson CreateInstance()  
         {  
             
    string path = ConfigurationManager.AppSettings["AssemblyName"];  
             
    string className = ConfigurationManager.AppSettings["jsonClass"];  
             
    return Assembly.Load(path).CreateInstance(className) as IPerson;  
         }  
     }  
     
    static void Main(string[] args)  
         {  
             ICreatePerson c1 
    = new CreateKernelFactory();  
             IPerson p1 
    = c1.CreateInstance();  
             ICreatePerson c2 
    = new CreateJsonFactory();  
             IPerson p2 
    = c2.CreateInstance();  
             Console.WriteLine(p1.GetName());  
             Console.WriteLine(p2.GetName());  
             Console.ReadKey();  
         }


    3.策略模式

    有时候你会发现有些需求其实大体都是一样的,同一类的,就是计算方式不同,这时就可以用策略模式:

    代码
     public interface IBuy  
         {  
             
    string GetCharge();  
         }  
       
         
    public class CashBuy : IBuy  
         {  
             
    double charge;  
             
    double cut;  
             
    public CashBuy(double charge, double cut)  
             {  
                 
    this.charge = charge;  
                 
    this.cut = cut;  
             }  
             
    public string GetCharge()  
             {  
                 
    return (charge - cut).ToString();  
             }  
         }  
       
         
    public class CreditBuy : IBuy  
         {  
             
    double charge;  
             
    double precent;  
             
    public CreditBuy(double charge, double precent)  
             {  
                 
    this.charge = charge;  
                 
    this.precent = precent;  
             }  
             
    public string GetCharge()  
             {  
                 
    return (charge * precent).ToString();  
             }  
         }  
       
         
    public class Context  
         {  
             IBuy buy;  
             
    public Context(IBuy buy)  
             {  
                 
    this.buy = buy;  
             }  
       
             
    public string GetCharge()  
             {  
                 
    return buy.GetCharge();  
             }  
         }  
       
         
    static void Main(string[] args)  
             {  
                 Context c1 
    = new Context(new CashBuy(20040));  
                 Context c2 
    = new Context(new CreditBuy(2007));  
                 Console.WriteLine(c1.GetCharge());  
                 Console.WriteLine(c2.GetCharge());  
                 Console.ReadKey();  
             }


     你会发现在这里不再用接口new出一个个具体对象,而统一用Context对象,并通过Context得到结果.其实这通过工厂模式也可以得到相同 的结果,但它们的测重点有所不同.举个例子:排序算法,我需要的是选择一种算法但这种算法是一种策略,而这些算法实际上是可以相互替代的,即快速排序,基 数排序都可实现问题,而我只要求选择一种.而不是工厂里面创建那样,创建产品A(他是根据要求,而不是选择,即只能创建A),他与产品B是不能互相替代 的。

    然而纯粹的策略模式需要A知道B具体构造了哪些对象,会出现在谈简单工厂时所出的那些问题,所以,我们常常把简单工厂与策略模式一起使用:

    4.简单工厂+策略模式

    代码
     public enum BuyType  
         {   
             Cash,  
             Credit  
         }  
       
         
    public interface IBuy   
         {  
             
    double GetPrice();  
         }  
       
         
    public class CashBuy : IBuy  
         {  
             
    double price;  
             
    double cut;  
       
             
    public CashBuy(double price, double cut)  
             {  
                 
    this.price = price;  
                 
    this.cut = cut;  
             }  
       
             
    public double GetPrice()  
             {  
                 
    return price - cut;  
             }  
         }  
       
         
    public class CreditBuy : IBuy  
         {  
             
    double price;  
             
    double precent;  
       
             
    public CreditBuy(double price, double precent)  
             {  
                 
    this.precent = precent;  
                 
    this.price = price;  
             }  
       
             
    public double GetPrice()  
             {  
                 
    return price * (1 - precent);  
             }  
         }  
       
         
    public class Content  
         {  
             IBuy buy 
    = null;  
       
             
    public Content(BuyType buyType, double price, double cut)  
             {  
                 
    string path = ConfigurationManager.AppSettings["SimpeFactoryAndStrategyAssemble"];  
                 
    string className = "";  
                 
    switch (buyType)  
                 {  
                     
    case BuyType.Cash:  
                         className 
    = ConfigurationManager.AppSettings["cash"];  
                         
    break;  
                     
    default:  
                         className 
    = ConfigurationManager.AppSettings["credit"];  
                         
    break;  
                 }  
                 
    //buy = Assembly.Load(path).CreateInstance(className, false, BindingFlags.Default, null, new object[] { price, cut }, null, null) as IBuy;  
                 Type type = Type.GetType(className, true);  
                 buy 
    = Activator.CreateInstance(type, price, cut) as IBuy;  
             }  
       
             
    public double GetPrice()  
             {  
                 
    return buy.GetPrice();  
             }  
         }  
       
         
    static void Main(string[] args)  
             {  
                 Content c1 
    = new Content(BuyType.Cash, 20040);  
                 Content c2 
    = new Content(BuyType.Credit, 2000.7);  
                 Console.WriteLine(c1.GetPrice().ToString());  
                 Console.WriteLine(c2.GetPrice().ToString());  
                 Console.ReadKey();  
             }


    Demo下载:

    http://ljzforever.qupan.com/?folder=951925

    参考的文章:

    简单工厂模式 & 策略模式——《大话设计模式》读书笔记1

    http://hi.baidu.com/springlie/blog/item/6052ad010f26670e1c958366.html

    单一职责原则和 & 开放-封闭原则——《大话设计模式》读书笔记2

    http://hi.baidu.com/springlie/blog/item/4d01d5c878efc01f7e3e6f59.html

    策略模式和抽象工厂模式差别在那里??我怎么感觉两个一个样!!为了区分而区分???

    http://topic.csdn.net/t/20050108/17/3709567.html

    深入浅出工厂模式

    http://blog.csdn.net/ai92/archive/2004/12/26/229825.aspx

    深入浅出策略模式

    http://blog.csdn.net/ai92/archive/2004/12/26/229825.aspx

    简单工厂模式 和 策略模式 学习笔记

     http://www.cnblogs.com/sun11086/archive/2009/02/06/1385510.html

    简单工厂模式与工厂方法模式

    http://hi.baidu.com/wookoo/blog/item/b49f1ac7f89d87ded1006097.html

    策略模式和工厂模式的不同

    http://www.cnblogs.com/ac1985482/archive/2009/03/07/1405608.html

  • 相关阅读:
    03014_properties配置文件
    Python 文件I/O
    Python面向对象
    Python CGI编程
    Python正则表达式
    Python使用SMTP发送邮件
    python操作mysql数据库
    Python多线程
    python XML解析
    给傻瓜用的SP2010开发--第一部分--理解SP开发平台--第一章节--理解SP促销讨论(2)--追踪SP源头
  • 原文地址:https://www.cnblogs.com/ljzforever/p/1681806.html
Copyright © 2011-2022 走看看