第08讲:面向对象编程六大原则助你写出优雅程序

设计类就是完成属性和方法的设计!

属性:类需要封装哪些数据!

方法:类要实现哪些功能(任务)!

考虑到每个人的思维角度不一样,使用的方法有差别,最后设计的属性和方法也有差异。只要道理上讲得通,就是合理的!这个道理是什么?今天我们学的就是这个“道理”!而这个道理就是我们要掌握的各种面向对象的原则!学习面向对象就是学习一系列的原则、方法、技巧、经验、设计模式等!后面高级的技能点,相对来说是容易!

面向对象六大原则

【1】单一职责(SRP)

单一职责SRP,一个对象所要完成的任务应该是明确的简称对象职责明确。也就是我们不要设计万能类!不好的做法:有的人设计窗体类或者其他的功能类,一个类中有一千两千行代码!这么多的代码,一定是能细分的!

以课程中的双色球彩票选号器项目为例!涉及到类:选号器、双色球类 –>业务类、数据类 窗体–>边界类,各司其职,各干其事,后续扩展:

  • 窗体类:获取用户操作行为和数据、展示相关数据
  • 双色球类:封装了我们购买的彩票数据
  • 选号器类:主要封装了用过请求的各种行为(比如:选号、存储、打印….)

【应用】:主要影响的是我们思考问题的角度和内容。

【2】开闭原则(OCP)

开闭原则也被称为“开放扩展、封闭修改原则,这个原则是说我们设计完一个项目后,用户的需求的经常是变化的,如果你的项目设计的非常好,当用户需求变化的时候,你的项目代码修改的非常少,甚至没有修改。只有增加的模块或者类(扩展)。生活举例:USB接口,可以扩展很多USB设备。这点在我们开发中处处在用,我们后面学习的各种设计模式、设计方法,很多都是围绕扩展来展开的。

【应用】:主要影响的是我们程序总体的设计、或者某些模块的设计。说白了就是把各种模式、方法你学会后一个运用。

比如:首先会讲到简单工厂!

Selector mySelector=new Selector();也就是说当我们new一个对象的时候,这个对象在编程阶段是明确的。

什么时候用这种方式呢?如果你要使用的对象是不变的,那么尽快放开使用。但是,如果我们程序要使用的这个对象,并不是唯一确定Selector本身,可能还有其他的对象选择。这时候,我们就不能直接new怎么办?我们就要考虑把对象创建过程封装!交给第三者完成。这个第三者可能是方法、类、或某些模块、第三方的库等。

Selector mySelector=【工厂方法或模块】;写成前边这种形式的话,我们在程序编写阶段是不能确定这个对象的,只有在程序运行阶段才能确定。这样做的结果是无论工厂方法内部如何变化,对我们调用者没有影响。

回到主题:用户需求的变化被封装到了工厂方法或模块中,这样的话,我们程序本身在需求变化的时候不修改,这种做法就遵循了开放封闭原则。这就解释了,后面我们为什么要学习各种设计模式和设计方法,就是这个道理。

【3】里氏替换原则(LSP)

里氏替换原则(这个就是我们即将讲到的继承中使用的),这个在我们讲完继承后,你会明白。也就是说父类出现的地方可以使用子类替换。这种通用性,可以延续到接口,也就是说,接口出现的地方,可以用接口实现类替换,这个也多态的基础!如果你不理解这个原则,C#编程你等于没学!

Class A{}

Class B:A {}

Class B:A {}

【1】如果A是普通类,我们可以A a=new A();
【2】如果A是抽象类,我们就得用 A a=new B(); 也就是说抽象类作为变量的类型,后面必须指向的是子类对象。

A a=new C();

A a=【工厂方法】返回一个B或C的对象!

【答疑】obejct类,能不能所有的控件都基于以上的方式使用。object o=new Button();

提示:学东西不能生搬硬套!

录播:是希望你能在掌握面向对象基础的情况下,更多的掌握技能点。积累项目开发经验提高熟练度。编程的方法。

直播:目的不仅是重点、难点、扩展知识的讲解。更多的是侧重:编程的艺术。

注意:前面,如果我们需要扩展,考虑扩展,可以使用我们上面的方法!但是你不要为了扩展而扩展。

object o=new Button();

【4】迪米特法则(LoD)

最小耦合原则(最小知道原则、最小知识原则),主要完成的是解耦。

思考:为什么要解耦?其实我们讲解各种原则是相互依赖,相互影响的,为什么难学,难用。

解耦:其实开闭原则,也是解耦的实现方法。所有的扩展,模式,都是在围绕解耦。

【应用】:后面我们给项目分层,分模块,都是在解耦。

【5】接口隔离原则(ISP)

接口隔离原则也被称为接口最小化原则,A模块–和B模块关联的时候,接口非常多,这种做法就不行!接口是一个广义概念!在讲方法的时候,特别提醒了各位,方法参数定义的时候,一般不要超过4、5个参数。如果方法参数太多,调用的时候非常麻烦!其实我说这个话的依据:就是这个原则!

解决方法:实体类,用对象作为参数!广义:当我们封装一个模块的功能时,首先设计接口,设计接口的时候,你也不要设计的过多。接口设计太多,意味着对象很多,方法很多。我们经常说一句话:鸡多了不下蛋,人多了打瞎乱!

【6】依赖倒置原则(DIP)

在现实生活中盖楼一般从第一层第一层盖起,然后是第二层、第三层……..顶层,从没有先盖顶层的情况,但编程可能就是相反的方式!为什么要倒置?也就是下层依赖上层,或者“细节”依赖“抽象”。有两个目的:第一个是扩展的需要。第二是团队协作的需要。

抽象的类型1:可以通过抽象类和抽象方法

/// <summary>
    /// 父类 :  抽象层
    /// </summary>
    abstract class Person
    {
        public int ID { get; set; }
        public string Name { get; set; }

        public void Study()
        {

        }
        //抽象方法
        public abstract void Having();
    }

重写时需要使用override关键字

    /// <summary>
    /// 男人继承自人类(通过继承可以直接使用父类的属性和方法)
    /// 细节层
    /// </summary>
    class Man : Person
    {
        public string CusAttrFromMan { get; set; }

        //一般情况必须要重写抽象方法...
        public override void Having()
        {
            throw new NotImplementedException();
        }
    }
    class Women : Person
    {
        public string CusAttriFromWomen { get; set; }

        public override void Having()
        {
            throw new NotImplementedException();
        }
    }

//扩展:增加其他的细节

抽象的类型2:通过接口类

团队协作:我们的架构师或者项目负责人,首先搭建项目框架,根据业务编写各种接口,把项目的核心业务都组件完。然后,具体的开发者,可以根据这个框架和接口来完成具体的细节开发。如果我们开发中项目非常大,必须把这种原则提醒的非常明显,才能够显示你的项目水平。可能会有各种框架的选择,或者自己的设计的框架。

后面会接触到的名词:面向接口编程(面向抽象编程)、面向服务编程、面向切面编程、webservice、webapi

面向对象编程–>面向接口编程(面向抽象编程)、面向服务编程、面向切面编程……..

后面学习:更多的是实践 —-> 再理论 —-> 再实践…..

理论联合实践,不断学习,不断强化,需要记住的是:一定的理论没有,你是无法实践好的!

© 版权声明
THE END
喜欢就支持一下吧
点赞61赞赏 分享
评论 抢沙发
匿名的头像 - 登山亦有道
提交
匿名的头像 - 登山亦有道

昵称

在 WordPress 上使用 Sticker Heo 增添互动时的乐趣吧 !

取消
昵称表情代码图片

    暂无评论内容