单例、工厂、抽象工厂、原型、建造者
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace DesignPattern.CreatingPattern
{
//为什么需要单例?
// 构造对象是要花时间的,并且多个实例也浪费资源,所以再某些情况下,可以让类只实例化一次,让类的实例始终是同一个
//公开静态字段public static Singleton = new Singleton();为啥不行?
// 不能保证其他人不去另外实例化
//单例必须三要素:1.类型是自己的私有字段 2.私有构造方法 3.公开方法返回自己的实例
//单例的应用:1.数据库连接池 2.全局唯一号码生成器(流水号生成器)
public class SingletonPattern
{
public static void Show()
{
{
ISingleton singleton1 = SingletonLazy.CreateInstance();
ISingleton singleton2 = SingletonLazy.CreateInstance();
bool isEqua = object.ReferenceEquals(singleton1, singleton2);
for (int i = 0; i < 5; i++)
{
Task.Run(() =>
{
ISingleton singleton = SingletonLazy.CreateInstance();
});
}//启动5个线程创建
}
{
ISingleton singleton1 = SingletonHungryStruct.CreateInstance();
ISingleton singleton2 = SingletonHungryStruct.CreateInstance();
bool isEqua = object.ReferenceEquals(singleton1, singleton2);
}
{
ISingleton singleton1 = SingletonHungryFiled.CreateInstance();
ISingleton singleton2 = SingletonHungryFiled.CreateInstance();
bool isEqua = object.ReferenceEquals(singleton1, singleton2);
for (int i = 0; i < 5; i++)
{
Task.Run(() =>
{
ISingleton singleton = SingletonLazy.CreateInstance();
});
}//启动5个线程创建
}
}
public static void ShowThreadSafe()
{
List<Task> taskList = new List<Task>();
for (int i = 0; i < 10_000; i++)
{
taskList.Add(Task.Run(() =>
{
SingletonHungryFiled singleton = SingletonHungryFiled.CreateInstance();
//singleton.Test();//线程不安全 得到的值小于10_0000
singleton.TestSafe();//线程安全 sum = 10_0000
}));
}
Task.WaitAll(taskList.ToArray());
Console.WriteLine($"现在sum={SingletonHungryFiled.CreateInstance().sum}");
}
}
public interface ISingleton
{
}
/// <summary>
/// 懒汉式
/// </summary>
public class SingletonLazy : ISingleton
{
//volatile关键字 保证线程安全的,修饰的变量只能被一个线程操作
private static volatile SingletonLazy _singleton = null;
private static readonly object obj = new object();//配合锁的推荐写法
private SingletonLazy()
{
Console.WriteLine("懒汉被创建");
}
public static SingletonLazy CreateInstance()
{
if (_singleton == null)//如果已经被实例化过,不走锁了-- 多线程提升效率
{
lock (obj)//锁的范围内只有一个线程,它是对引用的锁,所以只针对引用类型,
{
if (_singleton == null)
{
_singleton = new SingletonLazy();
}
}
}
return _singleton;
}
}
/// <summary>
/// 饿汉式 通过构造方法创建
/// </summary>
public class SingletonHungryStruct : ISingleton
{
private static SingletonHungryStruct _singleton = null;
private SingletonHungryStruct()
{
Console.WriteLine("饿汉被创建--静态构造");
}
//静态构造函数 由CLR保证第一次使用这个类型时调用且仅调用一次
static SingletonHungryStruct()
{
_singleton = new SingletonHungryStruct();
}
public static SingletonHungryStruct CreateInstance()
{
return _singleton;
}
}
/// <summary>
/// 饿汉式 通过构造方法创建
/// </summary>
public class SingletonHungryFiled : ISingleton
{
//静态字段 CLR保证在第一次使用这个类前,初始化且仅一次,比构造函数还早
private static SingletonHungryFiled _singleton = new SingletonHungryFiled();
private SingletonHungryFiled()
{
Console.WriteLine("饿汉被创建--静态字段");
}
public static SingletonHungryFiled CreateInstance()
{
return _singleton;
}
public int sum = 0;
//单例不保证线程安全
public void Test()
{
sum++;
}
//要保证线程安全,需要加锁
private static readonly object obj = new object();
public void TestSafe()
{
lock (obj)
{
sum++;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace DesignPattern.CreatingPattern
{
public class PrototypePattern
{
}
//原型模式和单例模式很像,就是返回的实例是拷贝的
//避免频繁创建对象,克隆速度比较快
//涉及深拷贝和浅拷贝问题
// 浅拷贝:对于值类型和字符串,复制值;对于引用类型复制引用
// 深拷贝:都是复制值
public class Prototype
{
private static Prototype _prototype = new Prototype();
private Prototype()
{
}
public static Prototype CreateInstance()
{
Prototype prototypeClone = (Prototype)_prototype.MemberwiseClone();//内存中复制对象
return prototypeClone;
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace DesignPattern.CreatingPattern
{
public class FactoryMethod
{
//通过工厂模式创建一个人类
public void Show()
{
IFactory factory = new HumanFactory();
IAnimal human = factory.CreateAnimal();
//为啥步直接Human human1 = new Human();呢?
// 减少对业务层的直接依赖,Human是业务类,工厂是我们加的中间层
// 业务类可能经常变化,非业务变化较少,两者分开
// 可以在中间层加一些其他功能
}
}
#region 工厂方法
//工厂方法相当于把简单工厂的每一步都分拆出来一个工厂,保证每个工厂的稳定
//转移对象创建
public interface IFactory
{
IAnimal CreateAnimal();
}
public class HumanFactory : IFactory
{
public IAnimal CreateAnimal()
{
Console.WriteLine("加一些其他功能");
return new Human();
}
}
public class CatFactory : IFactory
{
public IAnimal CreateAnimal()
{
return new Cat();
}
}
public class CattleFactory : IFactory
{
public IAnimal CreateAnimal()
{
return new Cattle();
}
}
#endregion
/// <summary>
/// 简单工厂并不属于23中设计模式之一
/// </summary>
public class SimpleFactory
{
public IAnimal GetAnimal(string animalName)
{
switch (animalName)
{
case "人": return new Human();
case "猫": return new Cat();
case "牛": return new Cattle();
default: return null;
}
}
}
public interface IAnimal
{
void Eat();
}
public class Human : IAnimal
{
public void Eat()
{
Console.WriteLine("人吃饭");
}
}
public class Cat : IAnimal
{
public void Eat()
{
Console.WriteLine("猫吃肉");
}
}
public class Cattle : IAnimal
{
public void Eat()
{
Console.WriteLine("牛吃草");
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace DesignPattern.CreatingPattern
{
//抽象工厂 = 工厂+约束
//约束 侧重的是产品簇的概念,约束中生成的是一组对象--一个产品簇
public class AbstractFactory
{
public void show()
{
//用高新小学抽象工厂创建高新 教室、老师、学生对象
AbstractFactorySchool school = new GaoXinSchoolFactory();
IClassRoom classRoom = school.CreateClassRoom();
ITeacher teacher = school.CreateTeacher();
IStudent student = school.CreateStudent();
}
}
public class GaoXinSchoolFactory : AbstractFactorySchool
{
public override IClassRoom CreateClassRoom()
{
return new ClassRoom("高新");
}
public override ITeacher CreateTeacher()
{
return new Teacher("高新");
}
public override IStudent CreateStudent()
{
return new Student("高新");
}
}
public class TuMenSchoolFactory : AbstractFactorySchool
{
public override IClassRoom CreateClassRoom()
{
return new ClassRoom("土门");
}
public override ITeacher CreateTeacher()
{
return new Teacher("土门");
}
public override IStudent CreateStudent()
{
return new Student("土门");
}
}
//抽象工厂强调的是产品簇
public abstract class AbstractFactorySchool
{
public abstract IClassRoom CreateClassRoom();
public abstract ITeacher CreateTeacher();
public abstract IStudent CreateStudent();
}
public interface IClassRoom
{
string Id { set; get; }
}
public interface ITeacher
{
string Id { set; get; }
}
public interface IStudent
{
string Id { set; get; }
}
public class ClassRoom : IClassRoom
{
public string Id { set; get; }
public ClassRoom(string id)
{
Id = id;
}
}
public class Teacher : ITeacher
{
public string Id { set; get; }
public Teacher(string id)
{
Id = id;
}
}
public class Student : IStudent
{
public string Id { set; get; }
public Student(string id)
{
Id = id;
}
}
}