常用设计模式
设计模式一套被反复使用,多数人知晓的代码设计经验的总结,实现可重用代码,使代码更容易被理解,保证代码可靠性。
总体来说,设计模式分为三大类:
创建型模式(五种):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
结构型模式(七种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式
行为型模式(十一种):策策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
常见的设计模式介绍:
1、单例模式
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
主要解决:一个全局使用的类频繁地创建与销毁。
何时使用:当您想控制实例数目,节省系统资源的时候。
如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
关键代码:构造函数是私有的。
应用实例: 1、一个党只能有一个书记。 2、Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行。 3、一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。
优点: 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。 2、避免对资源的多重占用(比如写文件操作)。
缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
使用场景: 1、要求生产唯一序列号。 2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。 3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。
注意事项:getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成 instance 被多次实例化。
2、简单工厂模式
解决”单个对象”的问题,工厂类与产品类一一对应关系。
意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
优点:符合开闭原则,单一职责原则。
缺点:一个工厂类只生产一个产品方法,增加产品方法需要增加工厂类。
使用场景:工厂模式讲的是一个华为手机工厂生产一个华为手机,要生产其他的产品需另加工厂。
何时使用:我们明确地计划不同条件下创建不同实例时通过if或者switch来使用。
如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。
关键代码:创建过程在其子类执行。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; // 抽象产品类 abstract class Product { public abstract void Operation(); } // 具体产品类 A class ConcreteProductA : Product { public override void Operation() { Console.WriteLine("具体产品 A 的操作"); } } // 具体产品类 B class ConcreteProductB : Product { public override void Operation() { Console.WriteLine("具体产品 B 的操作"); } } // 简单工厂类 class SimpleFactory { // 根据参数创建不同的产品对象 public static Product CreateProduct(string productType) { switch (productType) { case "A": return new ConcreteProductA(); case "B": return new ConcreteProductB(); default: throw new ArgumentException("无效的产品类型"); } } } // 客户端 class Client { static void Main(string[] args) { // 创建产品 A Product productA = SimpleFactory.CreateProduct("A"); productA.Operation(); // 创建产品 B Product productB = SimpleFactory.CreateProduct("B"); productB.Operation(); // 尝试创建无效的产品类型 try { Product productC = SimpleFactory.CreateProduct("C"); productC.Operation(); } catch (ArgumentException ex) { Console.WriteLine(ex.Message); } } }
3、抽象工厂模式
解决”一系列对象”的问题,工厂类与产品类是一对多的关系(一对应一系列想依赖的产品)。
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
使用场景:抽象工厂模式讲的是一个华为手机工厂可以生产一系列的华为手机产品(手机、耳机、充电器)。
何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
优点:在一个产品族里面,定义多个产品,一个工厂只生产该工厂的产品。
缺点:新增产品时违反开闭原则。
关键代码:在一个工厂里聚合多个同类产品。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; // 抽象产品类 A abstract class AbstractProductA { public abstract void Operation(); } // 具体产品类 A1 class ConcreteProductA1 : AbstractProductA { public override void Operation() { Console.WriteLine("具体产品 A1 的操作"); } } // 具体产品类 A2 class ConcreteProductA2 : AbstractProductA { public override void Operation() { Console.WriteLine("具体产品 A2 的操作"); } } // 抽象产品类 B abstract class AbstractProductB { public abstract void Operation(); } // 具体产品类 B1 class ConcreteProductB1 : AbstractProductB { public override void Operation() { Console.WriteLine("具体产品 B1 的操作"); } } // 具体产品类 B2 class ConcreteProductB2 : AbstractProductB { public override void Operation() { Console.WriteLine("具体产品 B2 的操作"); } } // 抽象工厂类 abstract class AbstractFactory { public abstract AbstractProductA CreateProductA(); public abstract AbstractProductB CreateProductB(); } // 具体工厂类 1 class ConcreteFactory1 : AbstractFactory { public override AbstractProductA CreateProductA() { return new ConcreteProductA1(); } public override AbstractProductB CreateProductB() { return new ConcreteProductB1(); } } // 具体工厂类 2 class ConcreteFactory2 : AbstractFactory { public override AbstractProductA CreateProductA() { return new ConcreteProductA2(); } public override AbstractProductB CreateProductB() { return new ConcreteProductB2(); } } // 客户端 class Client { static void Main(string[] args) { // 使用工厂 1 创建产品家族 AbstractFactory factory1 = new ConcreteFactory1(); AbstractProductA productA1 = factory1.CreateProductA(); AbstractProductB productB1 = factory1.CreateProductB(); productA1.Operation(); productB1.Operation(); // 使用工厂 2 创建产品家族 AbstractFactory factory2 = new ConcreteFactory2(); AbstractProductA productA2 = factory2.CreateProductA(); AbstractProductB productB2 = factory2.CreateProductB(); productA2.Operation(); productB2.Operation(); } }
4、观察者模式
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
如何解决:使用面向对象技术,可以将这种依赖关系弱化。
关键代码:在抽象类里有一个 ArrayList 存放观察者们。