解决问题:建立对象,将建立对象的任务交给另外一个对象完成。web
组成:安全
优势:客服了简单工厂违背开放封闭原则的缺点。服务器
优势:让具体的建立实例过程与客户端分离,客户端是经过他们的抽象接口操纵实例,产品的具体类名也被多线程
具体工厂的实现分离,不会出如今客户端代码中。并发
缺点:若是新增一个业务产品,就须要修改原有各工厂子类,添加生产新产品的方法,同时还须要新增每一个负载均衡
工厂生产的具体业务产品类,才能够彻底实现。函数
优势:客户不须要知道具体建立对象,隐藏了类的实例是如何被建立的。性能
简单工厂:网站
UML图:ui
伪代码实现:
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图:
伪代码实现:
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图:
伪代码:
//客户端 IFactory fac=new SqlserverFactory();//new AcessFactory(); IUser iu=fac.CreatUser(): iu.insert(); IDepartment id=fac.CreateDepartment(); id.insert();
建造者模式:
理解:指挥者指挥某某作事。好比常见举例饭店经理指挥收银员点餐、工做人员出餐就是这个思想。
UML图:
伪代码实现:
/// 事情 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图:
伪代码实现:
//浅复制 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图:
伪代码实现,“懒汉式单例类”(被第一次引用时才会本身实例化):
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; } }