凭什么要用面向对象编程(补充)

接上篇 面向对象重要设计原则概述

★2007-10-02  08:00 小菜在家中准备
小菜开始准备给人家讲座的内容,一开始都很顺利。可是当要把不同的验证方式给细化时,发现了问题。

 
24 原有的接口实现关系图

如果要再把是用户名密码验证,还是指纹验证的代码加进来,应该如何写具体的实现类呢?

 
25 SqlServer实现类改造
此时你会发现,如果要实现这个功能,你必须在你的每个实现类中写出上面的判断语句,如果某一天要增加一种数据访问(比如MySql)你就得再写一遍类似的代码,如果某天增加一个用户验证的方式(比如人脸识别验证),你就得改动所有的实现类的分支判断。这显然是让人难以接受的。

小菜决定换一种思路
 

26 多个类的多重继承

也就是把分支判断的语句,通过继承的方式给分解掉,这样每一种实现都体现成为一个类。只要有新的数据访问或者用户验证方式,不外乎就是增加类就可以了。应该是解决了问题。

可是,看着这张图,小菜感觉不到设计的美。如果,我们增加一种数据访问(如MySql),我们需要增加至少四个类。如果我们增加一种验证方式(如人脸识别验证),那就需要每个数据访问下都继承一个类。目前是3*3共9个类,当扩展需求来了以后,类的增加会成为一个梦魇。

难道没有办法了吗?

1)当想不出解决办法时,分析自己的代码有什么容易被改变的地方,可能找到解决思路

回到那个接口

 
 
其实当我们要增加一种验证方式时,这个Users类也是要修改的。而且对于Users类来说,验证时通常只会用到当中的一两个属性,而现实中,Users类的属性如性别、生日、姓名等等都对验证来说没有意义。此时发现,验证和用户类本身还是有区别的,验证属性其实只是用户类一小部分属性而已。对于数据库来说,我们把用户名、密码、门禁卡编号、指纹数据存到Users表里的字段中是没有问题,可在面向对象编程时,将它们混在一起的确不利于应对变化。

2)当想不出解决办法时,再次仔细分析需求,并找出需求的本质是个很好的办法

登录是为了验证用户,验证有很多种表现形式。网络上的验证通常就是用户名和密码,但随着科技的进步,指纹试别、面部试别等技术都可以成为验证用户的手段。而这一切,其本质上,验证就是抽象概念,其它都是它的实现方式。那么验证应该就是接口,那几个表现方式是它的实现类。OK,思路有了。

思路:提炼出验证接口,将不同的验证实现这个接口,将用户管理接口的登录方法聚合这个接口。

 
27 相对较好实现办法的类图

将验证分离成一个接口,不同的验证方式不过是验证的一种表现形式。

 
 

 
32 更改了原用的参数,改用验证接口

 
33 Sqlserver实现类的代码(其它实现类类似)

 
34 用户名密码登录用的界面事件代码

 
35 指纹登录的界面代码

此时,小菜算是松了口气,不管是增加新的数据访问或是增加新的验证方式,都只不过是增加一个类就可以了,这就把“开放封闭原则”和“依赖倒转原则”再次得到了充分的体现。实际上,在不知不觉中,小菜已经使用了“简单工厂模式”、“门面(外观)模式”、“桥接模式”。在这个完整的例子中,并不是为了模式而模式,而是在需求的变更中,为了应对需求的变化而不断演变出来。相信以后需求再有变化,也可以从容面对。

最后,小菜在新建文档的标题处打上“凭什么要用面向对象编程”,开始培训材料的写作。

附:有朋友质疑一个登录功能写这么多的代码的必要性。我想说的是,这是一个讲解面向对象编程的例子,为了理解的需要,杜撰了一些需求的变更。通过这样的讲解,是希望你可以在你的编程工作中,学会如何去设计和考虑问题,更好的应用面向对象技术来创建可维护、可扩展、可复用,并灵活性好的程序。

源代码下载

时间: 2024-10-09 23:07:35

凭什么要用面向对象编程(补充)的相关文章

[.net 面向对象编程基础] (20) LINQ使用

[.net 面向对象编程基础] (20)  LINQ使用 通过上节LINQ的基础知识的学习,我们可以开始使用LINQ来进行内存数据的查询了,我们上节说了LINQ的定义为:Language Integrated Query(语言集成查询)的简称,它是集成在.NET编程语言中的一种特性. 1.LINQ的构架 从这幅图中,我们可以知道LINQ包括五个部分:LINQ to Objects.LINQ to XML.LINQ to SQL.LINQ to DataSet.LINQ to Entities.

JAVA的面向对象编程--------课堂笔记

JAVA的面向对象编程--------课堂笔记 面向对象主要针对面向过程. 面向过程的基本单元是函数.   什么是对象:EVERYTHING IS OBJECT(万物皆对象)   所有的事物都有两个方面: 有什么(属性):用来描述对象. 能够做什么(方法):告诉外界对象有那些功能. 后者以前者为基础. 大的对象的属性也可以是一个对象.   为什么要使用面向对象: 首先,面向对象符合人类看待事物的一般规律. 对象的方法的实现细节是屏蔽的,只有对象方法的实现者了解细节. 方法的定义非常重要.方法有参

python学习笔记day6【面向对象编程】

面向对象编程 一.编程范式:编程的方法论.程序员编程的“套路”及“特点”特点总结,抽象成方法.规范. 二.面向对象编程介绍: 1.描述 世界万物,皆可分类:世间万物,皆为对象:只要是对象,就肯定属于某种品类:只要是对象,就肯定有一定的属性. opp编程(面向对象编程)的抽象机制是将待解问题抽象为面向对象的程序中的对象.利用封装使每个对象都拥有个体的身份.程序便是成堆的对象,彼此通过消息的传递,请求其它对象 进行工作.也可以说opp编程是利用“类”和“对象”来创建各种模型来实现对真实世界的描述.

java面向对象编程(八)--抽象类、接口

1.抽象类 1.1抽象类概念 当父类的一些方法不能确定时,可以用abstract关键字来修饰该方法[抽象方法],用abstract来修饰该类[抽象类]. //抽象类的必要性[Demo124.java] public class Demo124 { public static void main(String[] args) { //Animal an=new Animal();抽象类不允许实例化 Animal an=new Cat(); an.cry(); an=new Dog(); an.cr

JAVA的面向对象编程

面向对象主要针对面向过程. 面向过程的基本单元是函数. 什么是对象:EVERYTHING IS OBJECT(万物皆对象) 所有的事物都有两个方面: 有什么(属性):用来描述对象. 能够做什么(方法):告诉外界对象有那些功能. 后者以前者为基础. 大的对象的属性也可以是一个对象. 为什么要使用面向对象: 首先,面向对象符合人类看待事物的一般规律. 对象的方法的实现细节是屏蔽的,只有对象方法的实现者了解细节. 方法的定义非常重要.方法有参数,也可能有返回值. 注意区分:对象(本身).对象的实现者.

进击的Python【第六章】:Python的高级应用(三)面向对象编程

Python的高级应用(三)面向对象编程 本章学习要点: 面向对象编程介绍 面向对象与面向过程编程的区别 为什么要用面向对象编程思想 面向对象的相关概念 一.面向对象编程介绍 面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是一种程序设计范型,同时也是一种程序开发的方法.对象指的是类的实例. 已经被证实的是,面向对象程序设计推广了程序的灵活性和可维护性,并且在大型项目设计中广为应用. 此外,支持者声称面向对象程序设计要比以往的做法更加便于学习,因为它

java面向对象编程(1)-类与对象

1.问题的提出      张老太养了两只猫猫:一只名字叫小白,今年3岁,白色.还有一只叫小花,今年100岁,花色.请编写一个程序,当用户输入小猫的名字时,就显示该猫的名字,年龄,颜色.如果用户输入的小猫名错误,则显示张老太没有这只猫. //用前面学习过的知识写出代码如下: public class Demo107{ public static void main(String []args){ int a=49;//输入的名字49,50 int cat1age=3; //第一只猫 String

第五章 面向对象编程设计与开发——续3

5.9--封装 如何隐藏 在python中用双下划线开头的方式将属性隐藏起来(设置成私有的) #其实这仅仅是一种变形操作 #类中所有双下划线开头的名称如_x都会自动形成:_类名_x的形式: class A: _N=0#类的数据属性就应该是共享的,但是语法上是可以把类的数据属性设置成私有的如_N,会变形为_A_N def _init_(self): self._x=10#变形为self._A_X def _foo(self):#变形为_A_foo print('form A') def bar(s

面向对象编程——类(class)1

一.函数式编程 与 面向对象编程 def 函数名(参数): pass class 类名: def 函数名(self,参数): # self必填 pass z1 = 类名() # 这时,调用对象 z1,self参数即为 z1 例1: class bar: def foo(self,arg): print(self,arg) z1 = bar() print(z1) # <__main__.bar object at 0x0000019BC3088D30> z1.foo('wjz') # <