首页 > 其他分享 >DesignPatternPrinciple-设计模式原则

DesignPatternPrinciple-设计模式原则

时间:2023-02-22 13:55:19浏览次数:35  
标签:Name 原则 people System new using 设计模式 public DesignPatternPrinciple

1. 单一职责原则(Single Responsibility Principle)类T负责两个不同的职责:职责P1,职责P2。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignPatternPrinciple.SRP
{
    /// <summary>
    /// 单一职责原则:类T负责两个不同的职责:职责P1,职责P2。当由于职责P1需求发生改变而需要修改类T时,
    /// 有可能会导致原本运行正常的职责P2功能发生故障。
    /// 
    /// 一个类只负责一件事儿
    /// 面向对象语言开发,类是一个基本单位,单一职责原则就是封装的粒度
    /// 
    /// 写分支判断,然后执行不同的逻辑,其实这就违背了单一职责原则,但是功能是可以实现的
    /// 
    /// 拆分父类+子类,
    /// 每个类很简单,简单意味着稳定 意味着强大
    /// (现在的东西没有以前经用,因为功能多了,这不坏那坏了)
    /// 
    /// 拆分后,也会造成代码量的增加,
    /// 类多了,使用成本也高(理解成本)
    /// 
    /// 究竟该什么时候使用单一职责原则呢?
    /// 如果类型足够简单,方法够少,是可以在类级别去违背单一职责
    /// 如果类型复杂了,方法多了,建议遵循单一职责原则
    /// 
    /// 方法级别的单一职责原则:一个方法只负责一件事儿(职责分拆小方法,分支逻辑分拆)
    ///   类级别的单一职责原则:一个类只负责一件事儿
    /// 类库级别的单一职责原则:一个类库应该职责清晰
    /// 项目级别的单一职责原则:一个项目应该职责清晰(客户端/管理后台/后台服务/定时任务/分布式引擎)
    /// 系统级别的单一职责原则:为通用功能拆分系统(IP定位/日志/在线统计)
    /// 
    /// </summary>
    public class SRPShow
    {
        public static void Show()
        {
            {
                Animal animal = new Animal("鸡");//呼吸空气
                animal.Breath();
                //animal.Action();
            }
            {
                Animal animal = new Animal("牛");//呼吸空气
                animal.Breath();
                //animal.Action();
            }
            {
                Animal animal = new Animal("鱼");//呼吸水
                animal.Breath();
                animal.Action();
            }
            {
                AbstractAnimal animal = new Chicken();
                animal.Breath();
                animal.Action();
            }
            {
                AbstractAnimal animal = new Fish();
                animal.Breath();
                animal.Action();
            }
        }
    }
}

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignPatternPrinciple.SRP
{
    /// <summary>
    /// 封装
    /// 动物类
    /// 简单意味着稳定
    /// </summary>
    public class Animal
    {
        private string _Name = null;
        public Animal(string name)
        {
            this._Name = name;
        }
        /// <summary>
        /// 这个方法就挺不稳定,经常各种分支变化经常修改
        /// </summary>
        public void Breath()
        {
            if (this._Name.Equals("鸡"))
                Console.WriteLine($"{this._Name} 呼吸空气");
            else if (this._Name.Equals("牛"))
                Console.WriteLine($"{this._Name} 呼吸空气");
            else if (this._Name.Equals("鱼"))
                Console.WriteLine($"{this._Name} 呼吸水");
            else if (this._Name.Equals("蚯蚓"))
                Console.WriteLine($"{this._Name} 呼吸泥土");
        }
        //BreathChicken  BreathFish

        //应该拆分了
        public void Action()
        {
            if (this._Name.Equals("鸡"))
                Console.WriteLine($"{this._Name} flying");
            else if (this._Name.Equals("牛"))
                Console.WriteLine($"{this._Name} walking");
            else if (this._Name.Equals("鱼"))
                Console.WriteLine($"{this._Name} Swimming");
            else if (this._Name.Equals("蚯蚓"))
                Console.WriteLine($"{this._Name} Crawling");
        }
    }
}

 

2. 里氏替换原则(Liskov Substitution Principle):任何使用基类的地方,都可以透明的使用其子类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignPatternPrinciple.LSP
{
    /// <summary>
    /// 里氏替换原则:任何使用基类的地方,都可以透明的使用其子类
    /// 继承、多态
    /// 继承:子类拥有父类的一切属性和行为,任何父类出现的地方,都可以用子类来代替
    /// 继承+透明(安全,不会出现行为不一致)
    /// 
    /// 1 父类有的,子类是必须有的;
    ///   如果出现了子类没有的东西,那么就应该断掉继承;
    ///   (再来一个父类,只包含都有的东西)
    /// 2 子类可以有自己的属性和行为
    ///   子类出现的地方,父类不一定能代替
    ///   白马非马
    /// 3 父类实现的东西,子类就不要再写了,(就是不要new隐藏)
    ///   有时候会出现意想不到的情况,把父类换成子类后,行为不一致
    ///   如果想修改父类的行为,通过abstract/virtual
    ///   
    /// 声明属性、字段、变量,尽量声明为父类(父类就能满足)
    /// 
    /// </summary>
    public class LSPShow
    {
        public static void Show()
        {
            Console.WriteLine("***************************");
            Poly.Test();
            {
                //People people = new Chinese();
                Chinese people = new Chinese();
                people.Traditional();
                //DoChinese(people);
                people.SayHi();
            }
            {
                Chinese people = new Hubei();
                people.Traditional();
                //DoChinese(people);
                people.SayHi();

            }
            {
                var people = new Hubei();
                people.Traditional();
                //DoChinese(people);
                people.SayHi();
            }
            {
                People people = new Japanese();
                people.Traditional();
                //要么上端调用去判断  不能写  因为Japanese没有Traditional
                //要么就只能在子类抛异常
            }
            {
                Hubei people = new Hubei();
                people.Traditional();
                DoChinese(people);
                DoHubei(people);
            }

            {
                //People people = new People();
                //Do(people);
            }

        }

        private static void DoChinese(Chinese people)
        {
            Console.WriteLine($"{people.Id} {people.Name} {people.Kuaizi}");
            people.SayHi();
        }



        private static void DoHubei(Hubei people)
        {
            Console.WriteLine($"{people.Id} {people.Name} {people.Kuaizi}");
            people.SayHi();
        }

    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignPatternPrinciple.LSP
{
    public class People
    {
        public int Id { get; set; }
        public string Name { get; set; }

        //abstract void Eat();
        public void Traditional()
        {
            Console.WriteLine("仁义礼智信 温良恭俭让 ");
        }
    }

    public class Chinese : People
    {
        public string Kuaizi { get; set; }
        public void SayHi()
        {
            Console.WriteLine("早上好,吃了吗?");
        }

    }

    public class Hubei : Chinese
    {
        public string Majiang { get; set; }
        public new void SayHi()
        {
            Console.WriteLine("早上好,过早了么?");
        }
    }

    //public class Animal//让People继承自Animal
    //{
    //    public int Id { get; set; }
    //    public string Name { get; set; }
    //}

    public class Japanese : People
    {
        //public int Id { get; set; }
        //public string Name { get; set; }
        //public new void Traditional()
        //{
        //    Console.WriteLine("忍者精神 ");
        //throw new Exception();
        //}
        //Traditional也会继承 但是Japanese又没有Traditional
        public void Ninja()
        {
            Console.WriteLine("忍者精神 ");
        }

    }

}


3. 依赖倒置原则(Dependence Inversion Principle)依赖倒置原则:上层模块不应该依赖于低层模块,二者应该通过抽象依赖

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignPatternPrinciple.DIP
{
    /// <summary>
    /// 依赖倒置原则:高层模块不应该依赖于低层模块,二者应该通过抽象依赖
    ///              依赖抽象,而不是依赖细节
    /// 抽象:接口/抽象类--可以包含没有实现的元素
    /// 细节:普通类--一切都是确定的
    /// 
    /// 面向抽象编程:尽量的使用抽象,80%的设计模式都是跟抽象有关
    /// 属性 字段  方法参数 返回值。。。尽量都是抽象
    /// 
    /// 
    /// </summary>
    public class DIPShow
    {
        public static void Show()
        {
            Console.WriteLine("**************DIPShow***************");
            Student student = new Student()
            {
                Id = 191,
                Name = "候鸟班长"
            };
            //Student-使用-手机
            //高层---------底层
            {
                iPhone phone = new iPhone();
                student.PlayiPhone(phone);
                student.PlayT(phone);
                student.Play(phone);
            }
            {
                Lumia phone = new Lumia();
                student.PlayLumia(phone);
                student.PlayT(phone);
                student.Play(phone);
            }
            {
                Honor phone = new Honor();
                student.PlayHonor(phone);
                student.PlayT(phone);
                student.Play(phone);
            }
            //依赖细节  高层就依赖了底层
            //手机扩展一下,学生就得改一下。。。手机多了怎么办
            {
                Mi phone = new Mi();
                student.PlayT(phone);
                student.Play(phone);
            }
            {
                Oppo phone = new Oppo();
                student.PlayT(phone);
                student.Play(phone);
            }
            //用泛型+父类约束其实就等同于用父类参数类型
            //面向抽象有啥好处? 
            //1 一个方法满足不同类型的参数,
            //2 还支持扩展,只要是实现了这个抽象,不用修改Student
            {
                //面向抽象后,不能使用子类的特别内容
                Mi phone = new Mi();
                student.Play(phone);
                //如果传递的是Mi,Bracelet是有的,但是方法确实不能用
                //编译器决定了是不能用Bracelet的(dynamic/反射是可以调用的)

                //不能常规调用,这个问题是解决不了的,
                //因为面向抽象不止一个类型,用的就是通用功能;非通用的,那就不应该面向抽象
            }
            //面向抽象,只要抽象不变,高层就不变
            //面向对象语言开发,就是类与类之间进行交互,如果高层直接依赖低层的细节,细节是多变的,那么低层的变化就导致上层的变化;如果层数多了,底层的修改会直接水波效应传递到最上层,一点细微的改动都会导致整个系统从下往上的修改(这就是大家经常加班的原因)
            //面向抽象,如果高层和低层没有直接依赖,而是依赖于抽象,抽象一般是稳定的,那低层细节的变化扩展就不会影响到高层,这样就能支持层内部的横向扩展,不会影响其他地方,这样的程序架构就是稳定的

            //依赖倒置原则(理论基础)---IOC控制反转(实践封装)---DI依赖注入(实现IOC的手段)
        }
    }
}

 

4. 接口隔离原则(Interface Segregation Principle):客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignPatternPrinciple.ISP
{
    /// <summary>
    /// 接口隔离原则:客户端不应该依赖它不需要的接口;
    ///              一个类对另一个类的依赖应该建立在最小的接口上;
    /// </summary>
    public class ISPShow
    {
        public static void Show()
        {
            Console.WriteLine("***************ISPShow*************");
            Student student = new Student()
            {
                Id = 191,
                Name = "候鸟班长"
            };
            //AbstractPhone定义了id branch call text    is  a
            //现有智能手机map movie online game..
            //是否该把这几个上升到AbstractPhone? 
            //不应该的,上升后,oldman也是手机,但是没有这些功能!
            //AbstractPhone就只能放入任何手机都必须具备的功能
            {
                OldMan phone = new OldMan();
                phone.Call();
                phone.Text();
            }
            //不适合放在抽象类,但是面向抽象编程,接口!
            //接口interface定义 can do   不局限产品
            //Camera能拍照,能录像
            //既然面向抽象,那么有这些功能的对象都得能传递进来
            //那就让Camera也去实现IExtend
            {
                Honor honor = new Honor();
                student.Happy(honor);
                student.Video(honor);
            }
            {
                Camera camera = new Camera();
                student.Video(camera);
            }
            //实现IExtend接口,Camera出现很多自己没有的功能,
            //不应该用这种大而全的接口
            {
                IExtendVideo camera = new Camera();
                student.Video(camera);
            }

            {
                IExtendHappy extend = new TV();
                student.Happy(extend);
            }
            {
                IExtendGame extend = new PSP();
                student.Happy(extend);
            }
            //拆下去,都拆成一个方法一个接口,肯定也不好!
            {
                //List<>
                //Dictionary
                //IList<T>        索引相关
                //ICollection<T>  集合相关操作
                //IEnumerable<T>  迭代器foreach
            }
            //接口到底该如何定义?  
            //1 既不能是大而全,会强迫实现没有的东西,也会依赖自己不需要的东西
            //2 也不能一个方法一个接口,这样面向抽象也没有意义的
            //按照功能的密不可分来定义接口,
            //而且应该是动态的,随着业务发展会有变化的,但是在设计的时候,要留好提前量,避免抽象的变化
            //没有标准答案,随着业务和产品来调整的

            //3 接口合并 Map--定位/搜索/导航   这种属于固定步骤,业务细节,尽量的内聚,在接口也不要暴露太多业务细节
        }
    }
}

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignPatternPrinciple.ISP
{
    public class Honor : AbstractPhone, IExtend, IExtendVideo, IExtendHappy
    {
        public override void Call()
        {
            Console.WriteLine("User {0} Call", this.GetType().Name);
        }

        public override void Text()
        {
            Console.WriteLine("User {0} Call", this.GetType().Name);
        }

        public void Photo()
        {
            Console.WriteLine("User {0} Photo", this.GetType().Name);
        }

        public void Online()
        {
            Console.WriteLine("User {0} Online", this.GetType().Name);
        }

        public void Game()
        {
            Console.WriteLine("User {0} Game", this.GetType().Name);
        }

        public void Map()
        {
            Console.WriteLine("User {0} Map", this.GetType().Name);
        }

        public void Pay()
        {
            Console.WriteLine("User {0} Pay", this.GetType().Name);
        }

        public void Record()//录音
        {
            Console.WriteLine("User {0} Record", this.GetType().Name);
        }

        public void Movie()
        {
            Console.WriteLine("User {0} Movie", this.GetType().Name);
        }
    }
}

5. 迪米特法则 (Law Of Demeter):一个对象应该对其他对象保持最少的了解。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignPatternPrinciple.LOD
{
    /// <summary>
    /// 迪米特法则(最少知道原则):一个对象应该对其他对象保持最少的了解。
    /// 只与直接的朋友通信。
    /// 面向对象语言---万物皆对象---类和类交互才能产生功能--这不就耦合了吗?
    /// 
    /// 类与类之间的关系:
    /// 纵向:继承≈实现(最密切)
    /// 横向:聚合> 组合> 关联> 依赖(出现在方法内部)
    /// 
    /// 高内聚低耦合
    /// 迪米特法则,降低类与类之间的耦合
    ///     只与直接的朋友通信,就是要尽量避免依赖更多类型
    /// 基类库(BCL--框架内置的)的类型除外     
    ///
    /// 迪米特,也会增加一些成本
    /// 
    /// 工作中有时候会去造一个中介/中间层
    /// 门面模式 中介者模式  分层封装
    /// 上层UI下订单---订单系统&支付系统&仓储&物流
    /// 门面模式--上层交互门面--门面依赖子系统
    /// 三层架构:UI---BLL---DAL
    /// 
    /// 去掉内部依赖
    /// 降低访问修饰符权限
    /// private
    /// protected
    /// internal
    /// protected internal 子类或者同类库
    /// public
    /// 
    /// 迪米特,依赖别人更少,让别人了解更少
    /// </summary>
    public class LODShow
    {
        public static void Show()
        {
            Console.WriteLine("************************");
            School school = new School()
            {
                SchoolName = "SchoolName",
                ClassList = new List<Class>()
                {
                    new Class()
                    {
                        ClassName="CN",
                        StudentList=new List<Student>()
                        {
                            new Student()
                            {
                                StudentName="Tony"
                            },
                            new Student()
                            {
                                StudentName="sada"
                            }
                        }
                    }
                }
            };

            school.Manage();
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignPatternPrinciple.LOD
{
    /// <summary>
    /// 学生
    /// </summary>
    public class Student
    {
        public int Id { get; set; }
        public string StudentName { get; set; }
        public int Height { private get; set; }

        public int Salay;

        public void ManageStudent()
        {
            Console.WriteLine(" {0}Manage {1} ", this.GetType().Name, this.StudentName);
        }
    }
}

6: 开闭原则 (Open Closed Principle):对扩展开发,对修改关闭

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignPatternPrinciple.OCP
{
    /// <summary>
    /// 开闭原则:对扩展开发,对修改关闭
    ///    修改:修改现有代码(类)
    ///    扩展:增加代码(类)
    /// 面向对象语言是一种静态语言,最害怕变化,会波及很多东西 全面测试
    /// 最理想就是新增类,对原有代码没有改动,原有的代码才是可信的
    /// 
    /// 开闭原则只是一个目标,并没有任何的手段,也被称之为总则
    ///     其他5个原则的建议,就是为了更好的做到OCP
    ///     开闭原则也是面向对象语言开发一个终极目标
    ///     
    /// 如果有功能增加/修改的需求:
    /// 修改现有方法---增加方法---增加类---增加/替换类库
    /// </summary>
    public class OCPShow
    {
        public static void Show()
        {
            Console.WriteLine("*************OCPShow***********");
       
        }
    }
}

 

标签:Name,原则,people,System,new,using,设计模式,public,DesignPatternPrinciple
From: https://www.cnblogs.com/tx1185498724/p/17144052.html

相关文章

  • 智能合约的设计模式
    合约自毁模式合约自毁模式用于终止一个合约,这意味着将从区块链上永久删除这个合约。一旦被销毁,就不可能调用合约的功能,也不会在账本中记录交易。现在的问题是:“为什么......
  • 用一个例子学会适配器设计模式
    应用场景在软件系统中,经常会需要将一些现成的对象放到新的环境中使用,但是新的环境要求的接口,是这些现存对象所不能满足的。如何能利用现有的对象,又能满足新的引用环境所需......
  • 设计模式之动态代理
    JDK动态代理:publicinterfaceSubject{publicvoidshopping();} publicclassPersonimplementsSubject{@Overridepublicvoidshopping(){......
  • 设计模式
    单例模式(懒汉版)线程安全/***懒汉式*线程安全*/publicclassSingleton{//私有构造方法privateSingleton(){}//在成员位置创建该类的对象......
  • 性能测试的二八原则
    性能测试二八原则,响应时间2/5/8原则所谓响应时间的“2-5-8原则”,简单说,就是当用户能够在2秒以内得到响应时,会感觉系统的响应很快;当用户在2-5秒之间得到响......
  • CSS架构之BEM设计模式
    为什么需要CSS架构?其实在日常开发CSS当中,会遇到许多的问题,使用设计模式能够很好的解决。例如在日常开发项目,需要组件化时,组件内部的class样式类管理就非常的杂乱。大部分公......
  • 项目一众筹00_05Maven依赖概念,依赖范围、依赖传递性、依赖的原则:解决jar包冲突、依赖
    Maven概念_目录文章目录​​Maven概念_目录​​​​依赖范围​​​​依赖传递性​​​​依赖的原则:解决jar包冲突​​​​依赖排除​​​​统一版本管理​​依赖范围依赖传......
  • 责任链和策略设计模式-基于Java编程语言
    作者:京东物流钟磊1前言最近在梳理接口逻辑的时候发现,代码中使用的策略和责任链设计模式给我留下了非常深刻的印象。一个业务逻辑流程通常非常适合使用责任链和策略设计......
  • 看完这篇原型设计模式,还不会,请你吃瓜
    概述使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。在软件系统开发中,有时候会遇到这样的情况:我们需要用到多个相同实例,最简单直接的方法是通过多次......
  • 设计模式(十)----结构型模式之适配器模式
    1、概述如果去欧洲国家去旅游的话,他们的插座如下图最左边,是欧洲标准。而我们使用的插头如下图最右边的。因此我们的笔记本电脑,手机在当地不能直接充电。所以就需要一个插......