最常用的设计模式根据我的经验我把我经常用到的设计模式在这里做个总结,按照我的经验,它们的排序如下:1)单件模式、2)抽象工厂模式和工厂模式、3)适配器模式、4)装饰模式、5)观察者模式、6)外观模式 其他模式目前还很少用到。
单件模式
这是用的最多的模式,每一个正式的软件都要用它,全局配置、唯一资源、还有一个就是所有的工厂我都设计为单件模式,因此它的使用量大于工厂模式和抽象工厂模式之和。
是用来创建一个需要全局唯一实例的模式。只是需要纠正一点。singleton模式中,构造函数应该是protected.这样子类才可以扩展这个构造函数。
单件模式主要应用在以下场合: 对于一个类,占用的系统资源非常多。而且这些资源可以被全局共享,则可以设计为singleton模式,强迫全局只有一个实例 对于一个类,需要对实例进行计数。可以在createInstance中进行 并可以对实例的个数进行限制。 对于一个类,需要对其实例的具体行为进行控制,例如,期望返回的实例实际上是自己子类的实例。这样可以通过Singleton模式,对客户端代码保持透明。 用静态类可以代替单件吗
class Singleton
{
private static Singleton singleton = null;
private Singleton() {}
public static Singleton Instance
{
get{
if (null == singleton)
singleton = new Singleton();
return singleton;}
}
}
单例模式:单例的实现和上面模式演变中的最后一种很相似,只要把构造器私有便OK。
简单工厂模式
public class SteamedBread { public SteamedBread() // 构造方法 { } private double price=0.5; public double Price { get { return price; } set { price = value; } } } OK,产品对象建立好了,下面就是创建工厂(Factory)对象了。 public class Factory { public static SteamedBread CreateInstance() // 创建一个馒头(SteamedBread)对象 { return new SteamedBread(); } } 此时,客户端可以这样来调用: public class Client { public static void Main(string[] args) { //通过工厂创建一个产品的实例 SteamedBread sb = Factory.CreateInstance(); Console.WriteLine("馒头{0}元一个!", sb.Price); } } |
工厂模式
Public interface IFruit { } public class Orange:IFruit { public Orange() { Console.WriteLine("An orange is got!"); } } public class Apple:IFruit { public Apple() { Console.WriteLine("An apple is got!"); } } |
public class FruitFactory { public Orange MakeOrange() { return new Orange(); } public Apple MakeApple() { return new Apple(); } } |
string FruitName = Console.ReadLine(); IFruit MyFruit = null; FruitFactory MyFruitFactory = new FruitFactory(); switch (FruitName) { case "Orange": MyFruit = MyFruitFactory.MakeOrange(); break; case "Apple": MyFruit = MyFruitFactory.MakeApple(); break; default: break; } |
抽象工厂模式
示意性代码如下:
/// <summary> /// 食品接口----扮演抽象产品角色 /// </summary> public interface IFood { /// <summary> /// 每种食品都有销售价格,这里应该作为共性提升到父类或是接口来 /// 由于我们只需要得到价格,所以这里就只提供get属性访问器 /// </summary> double price{get;} } ------------------------------------------------------------------------------------ /// <summary> /// 馒头 /// </summary> public class SteamedBread:IFood { /// <summary> /// 构造方法 /// </summary> public SteamedBread() { } public double price { get { return 0.5; } } } ------------------------------------------------------------------------------------ /// <summary> /// 包子 /// </summary> public class SteamedStuffed:IFood { public SteamedStuffed() { } /// <summary> /// 销售价格 /// </summary> public double price { get { return 0.6; //0.6元一个 } } } ------------------------------------------------------------------------------------ /// <summary> /// 工厂角色 /// </summary> public class Factory { /// <summary> /// 创建一个馒头(SteamedBread)对象 /// </summary> /// <returns></returns> public static IFood CreateInstance(string key) { if (key == "馒头") { return new SteamedBread(); } else { return new SteamedStuffed(); } } } ------------------------------------------------------------------------------------ public class Client { public static void Main(string[] args) { //通过工厂创建一个产品的实例 IFood food = Factory.CreateInstance("馒头"); Console.WriteLine("馒头{0}元一个!", food.price); food = Factory.CreateInstance("包子"); Console.WriteLine("包子{0}元一个!", food.price); } } 此时的设计就已经完全符合简单工厂模式的意图了。顾客(Client)对早餐店营业员(Factory)说,我要“馒头”,于是营业员便根据顾客所提供的数据(馒头),去众多食品中找,找到了然后就拿给顾客。适配器模式
适配器模式有两种类的适配器和对象适配器,对象适配器更多一些,对象适配器的优点在很多大侠的著作了已经论述n次了,我这里不多啰嗦,我用的较多的原因还有一个,我从C++转到C#,由于C#不支持多重继承,我又不比较懒,较少定义interface,因此大多数情况下用C#时也只能使用对象适配器模式了。其实适配器和装饰模式功能上有很大的相似性,在下面的装饰模式中加以论述。
装饰模式
也叫油漆工模式,装饰模式和适配器模式相似都是用来利用现成代码加以调整来满足新的需求,其实采用设计模式的目的之一就是复用,这两个模式正是复用的体现。当你要用这两种模式的时候都是为你现有软件新增新的功能,一般情况下,如果你是让你的软件新增新的功能操作,你一般要用装饰模式,你如果要为软件新增功能支持,你最好选择适配器模式,你如果想为你的类新增操作你用装饰模式,你如果要引入其他来源的现成代码,你用适配器模式。
观察者模式
这个模式我用的多一个原因就是它可以实现事件功能,当然在C#中可以直接使用事件,但是在C++中却是用可以用此模式发挥的淋漓尽致了,网上曾经的一个考题(猫大叫一声,主人醒来,耗子跑开),就是使用这个模式的最好应用。
外观模式
开发就是能复用的地方就复用,这样才能节省资源,提高效率,外观模式也是一个提供复用其他现成代码的解决方案,你需要实现一个功能,可能现成的代码中就有此功能,但是现成代码可能远远多于你所需要的功能,此时你把这些功能封装起来,再重新提供一个你所需要的接口,这就是这个模式的精髓所在。
1.静态成员:
属性,方法和字段是对象实例所特有的,静态成员可看作是类的全局对象。 静态属性和字段可访问独立于任何对象实例的数据,静态方法可执行与对象类型相关而与对象实例无关的命令。使用静态成员时,不需要实例化对象。且不能用实例来调用静态字段,属性,方法。
2.静态类:
只包含静态成员,不能实例化,密封,不需要构造函数的定义