面向对象思想的头脑风暴(一)

简介:

团队中对面向对象的理论研究已经做了很长时间,大家对接口,封装,继承,多态以及设计模式什么的似乎都能说出点东西来,但当看代码时发现大家其实并不十分清楚具体怎么做,所以我就想了个题目让大家来做,然后进行了一次头脑风暴,过程记录如下:

题目内容:

需要处理三种产品图书,数码,消费,需要计算产品的税率,图书的税率为价格的0.1,数码和消费类产品为价格的0.11,需要获得三种产品的信息,图书和消费类产品的信息为:"名字:" + Name;,数码产品的信息为:"数码类名字:" + Name;

要求:符合ocp原则(不懂ocp原则的到网上去查,变化点在计税的方式可能改变,信息打印方式可能改变)

这里我给大家一个面向过程的版本,方便大家理解需求

 

代码

 

测试代码

 

代码

 

这个过程化的版本的问题如下:

1、当更改税率或获得信息时需要修改product类,这不符合ocp原则

2、product类的职责也太多了

当然如果就只是这么简单的需求的话,这个过程化的版本也不错,至少简单。

第一个方案:

 

Product类

 

 Tax类

 

复制代码
  class  Tax
    {
        
public   double  ComputeTax( double  price,  double  taxRate)
        {
            
return  price  *  taxRate;
        }
    }
复制代码

 

 

 

ProductInfo

 

这个方案其实完全没有解决问题,而且还比原来的方案更复杂了。新的税率仍然要改代码,新的信息仍然要改代码。

第二个方案:

 

Product

 

 

 

CreateProduct

 

 

interface  ITax
    {
        
double  CoumputeTax( double  price);
    }

 

Main

 

这个方案似乎是解决了问题,新的税率变化添加一个新类继承ITax接口,在客户端用即可。但这种方案显然属于知识学太多了,混用了委托与接口,无端的增加的复杂度,CreateProduct完全没有存在的必要。

第三种方案:

 

Product类

 

 

代码

 

这是使用委托来实现的方案,我觉得这个方案符合了需求,也符合了ocp原则,但和接口方案还是有区别的,我们先看看接口组合方案:

第四种方案:

 

代码

 

 

测试代码

 

代码

 

我觉得对于这个需求来说方案三和方案四都应该算是符合要求的比较好的解决方案,这两种方案各有优缺点。

 方案三(委托方案)的优点:

1、足够灵活

2、代码简单,类少

缺点:

1、缺乏限制,只要符合计税委托签名的方法就可以计算税率,往往会造成已实现的业务代码职责不够清晰。

方案四(接口方案)的优点:

1、职责明确

2、也足够灵活

缺点:

1、使用的类往往过多

 

接口和委托的区别:

接口(interface)用来定义一种程序的协定。实现接口的类或者结构要与接口的定义严格一致。接口(interface)是向客户承诺类或结构体的行为方式的一种合同,当实现某个接口时,相当于告诉可能的客户:“我保证支持这个接口的方法,属性等”,接口不能实例化,接口只包含成员定义,不包含成员的实现,成员的实现需要在继承的类或者结构中实现。 
C#中的委托是一种引用方法的类型,一旦为委托分配了方法,委托将与该方法具有完全相同的行为,委托方法的使用可以像其他任何方法一样具有参数和返回值。委托对象能被传递给调用该方法引用的代码而无须知道哪个方法将在编译时被调用。
从定义上来看似乎委托和接口没什么相似之处,但从隔离变化这个角度来看他们倒是有些相似之处,所以这里我们把他们放到一起来比较一番。

委托和接口都允许类设计器分离类型声明和实现。给定的接口可由任何类或结构继承和实现;可以为任何类中的方法创建委托,前提是该方法符合委托的方法签名。接口引用或委托可由不了解实现该接口或委托方法的类的对象使用。既然存在这些相似性,那么类设计器何时应使用委托,何时又该使用接口呢?

在以下情况中使用委托:

当使用事件设计模式时。委托是事件的基础,当需要某个事件触发外界响应时,使用委托事件比较合适。

当调用方不需要访问实现该方法的对象中的其他属性、方法或接口时。

需要方便的组合,使用委托可以利用+=,-=方便的组合方法。

当类可能需要该方法的多个实现时,使用多播委托。

在以下情况中使用接口:

当存在一组可能被调用的相关方法时。

当类只需要方法的单个实现时。

当使用接口的类想要将该接口强制转换为其他接口或类类型时。

当正在实现的方法链接到类的类型或标识时:例如比较方法。

使用单一方法接口而不使用委托的一个很好的示例是 IComparable 或 IComparable。IComparable 声明 CompareTo 方法,该方法返回一个整数,以指定相同类型的两个对象之间的小于、等于或大于关系。IComparable 可用作排序算法的基础,虽然将委托比较方法用作排序算法的基础是有效的,但是并不理想。因为进行比较的能力属于类,而比较算法不会在运行时改变,所以单一方法接口是理想的。

本文转自 你听海是不是在笑 博客园博客,原文链接:http://www.cnblogs.com/nuaalfm/archive/2010/04/09/1708543.html   ,如需转载请自行联系原作者

相关文章
|
网络安全 开发工具 git
|
6月前
|
数据采集 存储 机器学习/深度学习
Fuel 爬虫:Scala 中的图片数据采集与分析
Fuel 爬虫:Scala 中的图片数据采集与分析
|
6月前
|
Python
课时20:集合的运算
本内容介绍集合的运算,涵盖交集、并集、差集、异或集及子集等概念。通过Python代码示例详细说明各运算符(如 &、|、-、^、<=、<、>=、>)的使用方法,并解释其在实际编程中的应用。重点在于理解集合运算的基本原理及其在编程中的实现,帮助读者掌握集合运算的基础知识。
|
iOS开发 数据安全/隐私保护
[分享]错误“应用程序Xcode的这个版本不能与此版本的OS X配合使用”以及Mac源码和IOS开发资料分享
[分享]错误“应用程序Xcode的这个版本不能与此版本的OS X配合使用”以及Mac源码和IOS开发资料分享 安装Xcode时,出现“应用程序Xcode的这个版本不能与此版本的OS X配合使用”错误如下: 解决方案是: /system/libary/coreservice/SystemVersion.plist中的两个10.10为10.10.5 修改过程会提示无权限修改,要不要建立副本,点击提示框中的“复制”按钮,存到桌面上。
3879 0
|
机器学习/深度学习 自然语言处理 计算机视觉
三种能有效融合文本和图像信息的方法——特征拼接、跨模态注意、条件批量归一化
三种能有效融合文本和图像信息的方法——特征拼接、跨模态注意、条件批量归一化
三种能有效融合文本和图像信息的方法——特征拼接、跨模态注意、条件批量归一化
|
JSON API Nacos
nacos注册中心之服务地址的查询
nacos注册中心之服务地址的查询
1131 0
|
存储 SQL API
【对话科技】Flink技术介绍和新功能展望
2017年6月22号,由“京城学堂”和阿里巴巴集团技术发展部主办的“对话科技”系列讲座邀请到了Apache Flink项目的PMC成员,来自德国DataArtisans公司的Till Rohrmann,在北京阿里中心为关注实时计算技术的阿里同学做了一场关于Apache Flink技术发展的精彩分享。
|
jenkins 应用服务中间件 持续交付