• 常见的设计模式


    工厂模式

    这个模式有三个对象:工厂、用户、产品;这么说可能还有点抽象,说具体点,就是当我们在代码中需要生成一个类实例时,不直接去拿到这个类名,然后new;而是通过一个工厂类(例如EntityFactory),给该工厂类传要创建的类名的字符串,获取到最后生成的类实例;这样做的好处是,将对象的构造和使用隔离,使之模块化,工厂化。


    C#示例代码如下所示:

    //设计模式----工厂模式示例代码
    using System;
    using System.Collections.Generic;
    
    namespace ConsoleApp1
    {
        abstract class Animal
        {
            public string name;
            public Animal(string _name) { name = _name; }
    
            abstract public void Func() ;
        }
    
        class Dog: Animal
        {
            public Dog(string _name) :base(_name) { name = _name; }
            override public void Func()
            {
                Console.WriteLine($"Dog, name is {name}");
            }
        }
    
        class Monkey:Animal
        {
            public Monkey(string _name) : base(_name) { name = _name; }
            override public void Func()
            {
                Console.WriteLine($"Monkey, name is {name}");
            }
        }
    
        class Duck:Animal
        {
            public Duck(string _name) : base(_name) { name = _name; }
            override public void Func()
            {
                Console.WriteLine($"Duck, name is {name}");
            }
        }
    
        class AnimalFactory // 只需要传字符串到工厂,就能生成对应的类实例,然后利用多态,调用一样的接口,对应不一样的实现
        {
            private static AnimalFactory Instance;
            public static AnimalFactory GetInstance()
            {
                if(Instance == null)
                {
                    Instance = new AnimalFactory();
                }
                return Instance;
            }
    
          public dynamic CreateAnimal(string class_name, string animal_name)
            {
                Type type = Type.GetType("ConsoleApp1." + class_name); // 利用反射获取到对应类名的Type
                dynamic obj = Activator.CreateInstance(type, new object[] { animal_name}); //生成对应的实例
                return obj;
            }
        }
    
        class Program
        {
            
            public static void  Main()
            {
                Dictionary<string, string> nameDic = new Dictionary<string, string> 
                { 
                    { "Dog", "xiaowang" },
                    { "Duck", "xiaoli" },
                    { "Monkey", "xiaozhang" },
                };
    
                foreach(var namePair in nameDic)
                {
                    Animal animal = (Animal)AnimalFactory.GetInstance().CreateAnimal(namePair.Key, namePair.Value);
                    animal?.Func();
                }
            } 
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81

    单例模式

    在内存中只存在一个实例对象,通常的构成是:私有构造函数静态公共获取函数私有静态自身成员;创建单例的方式有懒汉模式饿汉模式静态内部类实现等。

    这是C++实现

    #include
    #include
    using namespace std;
    
    class Singleton1 // 懒汉模式
    {
    private:
    	static Singleton1* _instance;
    	Singleton1() { cout << "Singleton1 created !!!!"; }
    public:
    	static Singleton1* GetInstance()
    	{
    		if (_instance == NULL)
    		{
    			_instance = new Singleton1();
    		}
    		return _instance;
    	}
    };
    Singleton1* Singleton1::_instance; 
    //--------------------------------------------------------------------------
    class Singleton2 // 饿汉模式
    {
    private:
    	static Singleton2* _instance;
    	Singleton2() {cout<<"Singleton2 created !!!!"; };
    
    public:
    	static Singleton2* GetInstance()
    	{
    		return _instance;
    	}
    };
    
    Singleton2* Singleton2::_instance = new Singleton2();
    
    //------------------------------------------------------------------------------------
    
    class Singleton3 // 局部静态变量实现,还有一种是加锁模式,比较麻烦且耗,需要的百度下就行
    {
    private:
    	Singleton3() { cout << "Singleton3 created !!!!"; };
    public:
    	static Singleton3& GetInstance()
    	{
    		static Singleton3  instance;
    		return instance;
    	}
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    这是c#实现

    // 设计模式————单例模式(懒汉、饿汉、静态内部类实现)
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Text;
    using System.Threading;
    
    namespace ConsoleApp1
    {
    
        public class Singleton1 // 懒汉模式, 多线程不安全,会创建多个
        {
            private static Singleton1 _Singleton1 = null;
            private Singleton1()
            {
                Console.WriteLine("Singleton1被构造");
            }
            public static Singleton1 GetInstance()
            {
                if (_Singleton1 == null)
                {
                    _Singleton1 = new Singleton1();
                }
                return _Singleton1;
            }
        }
    
        public class Singleton2  // 饿汉模式,这里多线程运行状态下是线程安全的
        {
            private Singleton2() { Console.WriteLine("Singleton2被构造"); }
            private static Singleton2 Instance = new Singleton2();
            public static Singleton2 GetInstance() 
            {
                return Instance;
            }
        }
    
        public class Singleton3 // 内部静态类实现,多线程安全
        {
            private Singleton3() { Console.WriteLine("Singleton3被构造"); }
            private static class InnerClass
            {
                internal static Singleton3 instance = new Singleton3();
                static InnerClass() {}  //静态构造函数
            }
            public static Singleton3 GetInstance()
            {
                return InnerClass.instance;
            }
        }
    
        public class Singleton4 //静态构造函数, 构造线程安全,保证内存只有一个这个实例对象
        {
            private static Singleton4 Instance;
            private Singleton4() { Console.WriteLine("Singleton4被构造"); }
            static Singleton4()
            {
                Instance = new Singleton4();
            }
            public static Singleton4 GetInstance()
            {
                return Instance;
            }
        }
    
        public class Singleton5 // 惰性构造,构造线程安全
        {
            private static readonly Singleton5 instance = new Singleton5();
            private Singleton5() { Console.WriteLine("Singleton5被构造"); }
            static Singleton5() {}  // 静态构造,保证只调用一次,并且在调用一个静态方法或者属性时,初始化这个类
            public static Singleton5 Instance
            {
                get
                {
                    return instance;
                }
            }
        }
    
        class Program
        {
            public static void F1()
            {
                for (int i = 0; i < 10; ++i)
                {
                    var a = Singleton2.GetInstance();
                }
            }
            public static void Main()
            {
                // 验证多线程状态下的线程安全
                Thread thread1 = new Thread(new ThreadStart(F1));
                thread1.Start();
    
                Thread thread2 = new Thread(new ThreadStart(F1));
                thread2.Start();
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100

    这是网上有另外一个大佬,关于c#单例的讲解

    观察者模式

    当一个事件发生时,需要去通知其他订阅者;例如游戏里面常见的领完奖励之后刷新UI界面等等。通过注册的方式,实现事件的统一下触发以及代码的隔离。

    c#代码示例

    //设计模式----观察者/订阅者模式
    using System;
    
    namespace ConsoleApp1
    {
        public class Subscriber  // 发布者
        {
            public event Action mineActions;
            public Subscriber()
            {
            }
    
            public void registEvent(Action action)
            {
    
                mineActions += action;
            }
    
            public void unRegisterEvent(Action action)
            {
                mineActions -= action;
            }
    
            public void publishEvent()
            {
                mineActions?.Invoke();
            }
        }
    
        public abstract class ObserverBase
        {
            public string name;
            public ObserverBase(string _name)
            {
                name = _name;
            }
            public abstract void F1();
    
        }
    
        public class ObserverA: ObserverBase  // 订阅者A
        {
            public ObserverA(string _name):base(_name)
            {
                name = _name;
            }
            public override void F1()
            {
                Console.WriteLine($"this is {name} print !!!!!!!");
            }
        }
    
        public class ObserverB: ObserverBase // 订阅者B
        {
            public ObserverB(string _name) : base(_name)
            {
                name = _name;
            }
            public override void F1()
            {
                Console.WriteLine($"this is {name} print !!!!!!!");
            }
        }
    
        public class ObserverC : ObserverBase  // 订阅者C
        {
            public ObserverC(string _name) : base(_name)
            {
                name = _name;
            }
            public override void F1()
            {
                Console.WriteLine($"this is {name} print !!!!!!!");
            }
        }
    
    
        class Program
        {
    
            public static void Main()
            {
                Subscriber subscriber = new Subscriber();
                ObserverA observerA = new ObserverA("ObserverA");
                ObserverB observerB = new ObserverB("ObserverB");
                ObserverC observerC = new ObserverC("ObserverC");
    
                //订阅
                subscriber.registEvent(observerA.F1);
                subscriber.registEvent(observerB.F1);
                subscriber.registEvent(observerC.F1);
    
                //发布事件
                subscriber.publishEvent();
    
                //取消订阅
                subscriber.unRegisterEvent(observerA.F1);
                subscriber.unRegisterEvent(observerB.F1);
                subscriber.unRegisterEvent(observerC.F1);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102

    策略模式

    意图: 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

    主要解决: 在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。

    同一种方式有多重实现方法,例如

    • 登录到某个网站,可以用手机号登录、扫码登录、账号密码登录等,都是为了登录到同一个账号。
    • 去沃尔玛买购物,结账的时候可以使用现金,支付宝、微信以及购物卡,都是为了结账。
    • 高德地图导航时,可以选择步行、骑车、开车等不同方式,给出的路线不一样。

    代码示例

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Strategy
    {
    
        public abstract class StrategyBase
        {
            public abstract int F(int a, int b);
        }
    
        public class StrategyA: StrategyBase // 策略A
        {
            public override int F(int a, int b)
            {
                return a + b;
            }
        }
    
        public class StrategyB : StrategyBase // 策略B
        {
            public override int F(int a, int b)
            {
                return a - b;
            }
        }
    
        public class StrategyC : StrategyBase // 策略C
        {
            public override int F(int a, int b)
            {
                return a * b;
            }
        }
    
        public class Context // 代表上下文
        {
            StrategyBase strategyBase;
            public Context(StrategyBase _strategy)
            {
                strategyBase = _strategy;
            }
    
            public int F(int a, int b)
            {
                return strategyBase.F(a, b);
            }
    
        }
    
        public class Program
        {
            public static void Main()
            {
                Context a = new Context(new StrategyA()); // 使用策略A
                Context b = new Context(new StrategyB()); // 使用策略B
                Context c = new Context(new StrategyC()); // 使用策略C
                //调用的时候使用统一接口 F
                Console.WriteLine($"a.F(1,2) = {a.F(1, 2)}, b.F(1, 2) = {b.F(1, 2)}, c.F(1, 2) = {c.F(1, 2)}");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    在上述的示例代码中,对于同样的使用环境(Context类),当使用不一样的策略是,可以有不一样的实现。


    代理模式

    在真实的某个对象上再包一层代码,可以很方便的扩展其功能;例如游戏中的相机,我们可以在原生相机的基础上包装一层,然后可以在这一层代理里面加一些保护、实现一些原生接口函数的组合功能等。

    动机:限制对目标对象的直接访问,降低耦合度;还可以实现一些真实对象没有的接口或者一些现有功能的组合。

    示例代码:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace ConsoleApp1
    {
        class Subject // 真实对象
        {
            public void fun1()
            {
    
            }
    
            public void fun2()
            {
    
            }
    
            public void fun3()
            {
    
            }
        }
    
        class SubjectProxy  //代理对象,实现和真实对象一样的接口,可以限制对目标对象的直接访问,降低耦合度。
        {
            Subject subject;
            public SubjectProxy(Subject _subject)
            {
                subject = _subject;
            }
    
            public void fun1() // 这里做封装,可以打log,加保护
            {
                subject.fun1();
            }
    
            public void fun2()
            {
                subject.fun2();
            }
    
            public void fun3()
            {
                subject.fun3();
            }
        }
    
        public class Proxy
        {
            public static void Main()
            {
                SubjectProxy subjectProxy = new SubjectProxy(new Subject());
                subjectProxy.fun1();
                subjectProxy.fun2();
                subjectProxy.fun3();
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    装饰模式

    可以对原来的函数或者类进行扩展;对于类的装饰,可以实现组件式的代码结构,使得各个功能可以和方便的添加与删除,并且代码的逻辑也会很清晰;实现的功能是以组件的形式实现与继承相似的效果。

    解决的问题: 一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace ConsoleApp1
    {
    
        public abstract class Shape // 抽象基类
        {
            public abstract void Print();
    
        }
    
        public class Circle: Shape // 圆形
        {
            public override void Print()
            {
                Console.WriteLine("This is Circle Draw !!");
    
            }
        }
    
        public class Triangle : Shape // 三角形
        {
            public override void Print()
            {
                Console.WriteLine("This is Triangle Draw !!");
    
            }
        }
    
        public class Decorator: Shape  // 装饰类
        {
            public Shape shape;
    
            public Decorator(Shape _shape)
            {
                shape = _shape;
            }
            public override void Print()
            {
                Console.WriteLine("This is Triangle Draw !!");
    
            }
        }
    
        public class ColorShapeDecorator : Decorator  // 装饰类型1
        {
            public ColorShapeDecorator(Shape _Shape) : base(_Shape)
            {
    
            }
    
            public override void Print()
            {
                shape.Print();
            }
    
            public void Color()  //相当于在传进来Shape的基础上,增加了Color接口
            {
                // DoSomething
                Console.WriteLine("This is Color function !!");
            }
        }
    
        public class GeometryShapeDecorator : Decorator  // 装饰类型2
        {
            public GeometryShapeDecorator(Shape _Shape) : base(_Shape)
            {
    
            }
    
            public override void Print()
            {
                shape.Print();
            }
    
            public void GetArea()  //相当于在传进来Shape的基础上,增加了GetArea接口
            {
                // DoSomething
                Console.WriteLine("this is GetArea function !!");
            }
    
            public void GetGirth()  //相当于在传进来Shape的基础上,增加了GetGirth接口
            {
                // DoSomething
                Console.WriteLine("this is GetGirth function !!");
            }
        }
    
        class DecoratorTest
        {
            public static void Main()
            {
                Circle circle = new Circle();
                circle.Print();
                Console.WriteLine("--------------------------------------------");
                Triangle triangle = new Triangle();
                triangle.Print();
    
                Console.WriteLine("--------------------------------------------");
                ColorShapeDecorator ShapeDecoratorShape1 = new ColorShapeDecorator(circle);
                ShapeDecoratorShape1.Print();
                ShapeDecoratorShape1.Color(); // 在circle的基础上扩展了Color函数
    
                Console.WriteLine("--------------------------------------------");
                GeometryShapeDecorator ShapeDecoratorShape2 = new GeometryShapeDecorator(triangle);
                ShapeDecoratorShape2.Print();
                ShapeDecoratorShape2.GetArea(); // 在triangle的基础上扩展了GetArea、GetGirth等函数
                Console.WriteLine("--------------------------------------------");
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
  • 相关阅读:
    RK3568驱动指南|第五期-中断-第45章 自定义工作队列实验
    SAP ABAP——数据类型(三)【TYPE-POOL和INCLUDE嵌套定义类型】
    quartz框架(七)-JobStore
    数字电路与逻辑设计 之 组合电路的设计(多输出电路,全加器,乘法器)
    Docker手把手教程(二)核心命令
    Zookeeper客户端命令、JAVA API、监听原理、写数据原理以及案例
    基于云计算与深度学习的常见作物害虫识别系统的设计与实现
    topic是什么
    荧光染料BDP FL ceramide,BDP-FL神经酰胺
    2022年mvnrepository跳过人机验证
  • 原文地址:https://blog.csdn.net/qq_41841073/article/details/126649713