设计模式
* 设计模式
1、单例模式
- 静态方法,负责创建自己的唯一实例。static的资源只有一份
- 静态类与单例模式的区别:
1. 静态类不保存状态,仅提供一些静态方法或静态属性供使用;而单例是有状态的
2. 静态类不能用于继承多态,而实例单例虽实例唯一,却可以有子类继承
3. 静态类是一些方法属性的集合,而单例有唯一的实例
1.1 懒汉式
单线程:
public class Singleton { private static Singleton instance; //将构造方法设置为private,防止外界利用new新建实例 private Singleton() { } //获取本类实例的唯一方法 public static Singleton GetInstance() { if (instance == null) instance = new Singleton(); return instance; } } //调用 Singleton singleton1 = Singleton.GetInstance();
多线程:
public class MultiSingleton { private static MultiSingleton instance; private static readonly object syncRoot = new object(); //将构造方法设置为private,防止外界利用new新建实例 private MultiSingleton() { } public static MultiSingleton GetInstance() { //当不为null时,不用lock,减少资源消耗 if(instance == null) { //锁定 lock (syncRoot) { //当两个线程同时调用GetInstance()时,他们都可以通过第一重instance=null的判断,然后由于lock机制, //这两个线程只有一个进入,另一个等候,如果没有第二重的instance=null的判断,则第一个线程创建了实例,第二个线程由于过了第一重instance=null, //因此在没有第二重instance == null判断的情况下还是会创建实例。 if (instance == null) instance = new MultiSingleton(); } } return instance; } }
1.2 饿汉式
- 静态初始化,不需要显式的编写线程安全代码,即也可以解决多线程的问题
- 依赖公共语言运行库来初始化变量,变量标记为readonly只能在静态初始化期间或类的构造函数中初始化。
//必须设置为密封类,即不能被继承 public sealed class LazySingleton { //要声明为只读,表示只能静态初始化时或者类的构造函数中初始化 private static readonly LazySingleton instance = new LazySingleton(); private LazySingleton() { } public static LazySingleton GetInstance() { return instance; } }
1.3 总结
构造方法必须是private ,提供唯一一个static方法去获取实例
2、简单工厂模式
3、策略模式
- 一个类封装一个算法,实现一个算法借口,然后用Context进行维护调用
//抽象算法类 public interface IStrategy { //算法方法 void Add(); }
//具体策略1 public class ConcreteStrategyA : IStrategy { public void Add() { Console.WriteLine("具体策略1"); } } public class ConcreteStrategyB : IStrategy { public void Add() { Console.WriteLine("具体策略2"); } }
public class Context { public IStrategy strategy; //接收具体对象 public Context(IStrategy strategy) { this.strategy = strategy; } //调用方法 public void RunMethod() { strategy.Add(); } }
static void Main(string[] args) { //只需要改变这里初始化的实例即可 Context context = new Context(new ConcreteStrategyA()); context.RunMethod(); Console.ReadLine(); }