设计模式——建立型模式

解决问题:建立对象,将建立对象的任务交给另外一个对象完成web

组成:安全

  • 简单工厂:客户传递建立产品的类型到工厂类中去,工厂类根据类型实例化不一样的类。
  • 工厂方法Factory Method:定义一个用户建立对象的接口,让子类决定实例化哪个类。

                          优势:客服了简单工厂违背开放封闭原则的缺点。服务器

  • 抽象工厂Abstract Factory:提供一个建立一系列或相关依赖对象的接口,而无需指定它们具体的类。

                          优势:让具体的建立实例过程与客户端分离,客户端是经过他们的抽象接口操纵实例,产品的具体类名也被多线程

                                   具体工厂的实现分离,不会出如今客户端代码中。并发

                          缺点:若是新增一个业务产品,就须要修改原有各工厂子类,添加生产新产品的方法,同时还须要新增每一个负载均衡

                                   工厂生产的具体业务产品类,才能够彻底实现。函数

  • 建造者模式Builder:将一个复杂对象的构建与它的表示分离,使得一样的构建过程能够建立不一样的表示。
  • 原型模式Prototype:用原型实例指定建立对象的种类,而且经过拷贝这些原型建立新的对象。
  • 单例模式Singleton:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

优势:客户不须要知道具体建立对象,隐藏了类的实例是如何被建立的。性能

简单工厂:网站

UML图:ui

ZY4QAYA%DN0X0RN@T{}ZJBC[8]

伪代码实现:

public class 工厂
{
   public static 产品 Factory(string 产品名称)
   {
      Product result=null;
      switch(产品名称)
      {
         case"产品1":
            result=new 产品1();
            break;
         case"产品2":
            result=new 产品2();
            break;       
      }
      return result;
   }
}
客户端:
产品 =工厂.Factory("产品1");

工厂方法:

UML图:

image

伪代码实现:

public interface IFactory
{
   Product Factory();
}

public class FactoryProduct1 : IFactory
{
   public Product Factory()
   {
      return new Product1();
   }
}

//客户端
IFactory factory=new FactoryProduct1();
Product product=factory.Factory();

抽象工厂:

 

在工厂方法(只能生产一种业务产品)的基础上扩展而来,能生产多种业务产品,以下图的用户和部门;

可是一旦咱们须要增长一个新的业务产品,好比项目Project,则至少须要增长3个类,IProject、SqlserverProject、AccessProject,还须要修改IFactory、SqlserverFactory、AccessFactory,才能彻底实现。

可以使用简单工厂来改进抽象工厂,更进一步,经过反射+抽象工厂、反射+配置文件来进行改进。

UML图:

image

伪代码:

//客户端
IFactory fac=new SqlserverFactory();//new AcessFactory();

IUser iu=fac.CreatUser():
iu.insert();

IDepartment id=fac.CreateDepartment();
id.insert();

建造者模式:

理解:指挥者指挥某某作事。好比常见举例饭店经理指挥收银员点餐、工做人员出餐就是这个思想。

UML图:

image

伪代码实现:

/// 事情
public class Thing
{
   public void print(string Name)
   {
   }
}


// 工做者接口
public interface IWorker
{
   void doThing();
}

//具体工做者1
public class Worker1 : IWorker
{
   public void doThing()
   {
      // TODO: implement
   }
}

//具体工做者2
public class Worker2 : IWorker
{
   public void doThing()
   {
      // TODO: implement
   }
}

/// 指挥者
public class Director
{
   public Director(IWorker worker)
   {
      iWorker=worker;
   }
   
   public void command()
   {
      iworker.doThing();
   }
   public IWorker iWorker;

}


//客户端
Director director=new Director(new Worker1());
director.command();

 

原型模式:

     通俗的讲:就是为了复制一个对象,避免每次new类生成对象后须要重复设置相同的属性,复制后只需对个别须要个性化的属性设置个性化的值就能够了;避免每new一次,执行一次构造函数,若是构造函数的执行时间很长,屡次执行致使系统低效,在初始化信息不发生变化的状况下,克隆既隐藏了对象建立的细节,又能对性能大大的提升。

重点:须要注意深复制与浅复制两种的区别。

UML图:

image

伪代码实现:

//浅复制
class Program
    {
        static void Main(string[] args)
        {
            ShallowCopy sc1 = new ShallowCopy();
            ShallowCopy sc2 = (ShallowCopy)sc1.Clone();
            sc1.v[0] = 9;

            sc1.Display();//输出:9,2,3
            sc2.Display();//输出:9,2,3
            Console.Read();
        }
    }

    class ShallowCopy : ICloneable
    {
        public int[] v = { 1, 2, 3 };

        public Object Clone()
        {
            return this.MemberwiseClone();//浅复制
        }

        public void Display()
        {
            foreach (int i in v)
                Console.Write(i + ", ");
            Console.WriteLine();
        }
    }
//深复制
class Program
    {
        static void Main(string[] args)
        {
            DeepCopy dc1 = new DeepCopy();
            DeepCopy dc2 = (DeepCopy)dc1.Clone();
            dc1.v[0] = 9;

            dc1.Display();
            dc2.Display();
            Console.Read();
        }
    }

    class DeepCopy : ICloneable
    {
        public int[] v = { 1, 2, 3 };

        // 默认构造函数
        public DeepCopy()
        {
        }

        // 供Clone方法调用的私有构造函数
        private DeepCopy(int[] v)
        {
            this.v = (int[])v.Clone();
        }

        public Object Clone()
        {
            // 构造一个新的DeepCopy对象,构造参数为
            // 原有对象中使用的 v 
            return new DeepCopy(this.v);
        }

        public void Display()
        {
            foreach (int i in v)
                Console.Write(i + ", ");
            Console.WriteLine();
        }
    }

单例模式:

使用场景:

      一个网站的服务端程序,须要考虑怎样才能承载大量用户,在作web程序的时候有各类负载均衡的方案,其基本思想就是有一个统一的入口,而后由它来分配用户到各个服务器上去。须要考虑的问题是,即便在多线程的并发状态下,用户只能经过一个惟一的入口来分配,由此引入单例模式来实现这个惟一的入口。

不要滥用Singleton模式,只有非一个实例不可的状况下才考虑引入Singleton。不然,程序的可扩展性可能会受到限制。

UML图:

image

伪代码实现,“懒汉式单例类”(被第一次引用时才会本身实例化):

class Singleton
    {
        private static Singleton instance;
        private static readonly object syncRoot = new object();//程序运行时建立一个静态只读的进程辅助对象
        private Singleton()//构造方法改为private,堵死外界经过new来建立此类实例的可能
        {
        }
        public static Singleton GetInstance()
        {
            if (instance == null)//先判断实例是否存在,不存在再加锁处理,双重锁定
            {
                lock (syncRoot)
                {
                    if (instance == null)
                    {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }

C#提供了一种“静态初始化”方法,这种方法不须要开发人员显示的编写线程安全的代码,便可解决多线程环境下它是不安全的问题,称为“饿汉式单例类”(本身被加载时就实例化)。

public sealed class Singleton//sealed阻止派生发生,而派生可能会增长实例
    {
        private static readonly Singleton instance = new Singleton();//在第一次引用类的任何成员时建立实例,公共语言运行库负责处理变量初始化
        private Singleton() { }
        public static Singleton GetInstance()
        {
            return instance;
        }
    }
相关文章
相关标签/搜索