将勤补拙总输勤什么名字

火影名言_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
上传于||暂无简介
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩6页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢励志网名四字_网名名字_短美文网
励志网名四字
励志网名四字
励志网名四字
  学而时习之
  才学兼优
  笑对人生
  文行出处
  笃实好学
  文人学士
  据鞍读书
  博学多才
  敏而好学
  坚持不懈
  好好学习i
  不愧下学
  笃信好学
  刺股读书
  爱拼才会赢
  款学寡闻
  上进心@
  硕学通儒
  教学相长
  临池学书摘自:短美文
  学而优则仕
  犹恐失之
  博学洽闻
  悬梁刺股
  不耻下问
  人要靠自己@
  风雨兼程
  学海无涯
  秉烛达旦
  不耻下问
  记问之学
  高斋学士
  高才大学
  笃学好古
  钝学累功
  为自己打气,加油!
  不学无识
  程门立雪
  踌躇满志
  钜学鸿生
  困而学之
  夜以继
  生吞活剥
  拼自已想要A未来
  压力可以比天更高
  饱学之士
  效颦学步
  学而不厌
  上当学乖
  永不放弃
  铁棒磨成针
  嘴角上扬
  家学渊源
  囫囵吞枣
  穿壁引光
  枉辔学步
  新学小生
  独学寡闻
  名落孙山
  鸿儒硕学
  道山学海
  在孤单中奋斗
  争取第一
  诠才末学
  做最好的me
  学书不成
  抬头&那曙光
  闭户读书
  牙牙学语
  博览群书
  教然后之困
  牛角挂书
  永远志在四方
  映读书
  宿学旧儒
  k想要A未来
  笃学不倦
  看谁笑到最后
  虫鱼之学
  贫不学俭
  把思念改变成信念ㄟ
  融会贯通
  学剑不成
  好学不倦
  学而不厌
  顿学累功
  相信自已
  闭户读书
  勤学苦练
  才疏学浅
  专心致志
  勤学好问
  志在四方
  通才硕学
  下学上达
  长材茂学
  只要功夫深
  成王】茇
  教学相长
  随梦而飞
  囊萤照书
  然荻读书
  吃苦耐讴cf
  一切从零开始
  幼学壮行
  学老于
  博学强记
  各抒己见
  学疏才浅
  学书学剑
  力学不倦
  笃信好学
  持之以恒
  村学究语
  宏儒硕学
  锲而不舍
  学无止境
  学而不厌
  真才实学
  用非所学
  笃实好学
  通儒硕学
  映雪读书
  废寝忘食
  韦编三绝
  高才绝学
  不愧下学
  滴水穿石
  学然后知不足
  田里的守望者
  文江学海
  晚生后学
  孜孜不倦
  学然后知不足
  笃学好古
  学富五车
  勤学苦练
  至上励合
  不学无术
  口耳之学
  市民文学
  学识渊博
  孜孜不倦
  孤学坠绪
  耳闻则诵
  鹦鹉学舌
  囊萤映雪
  断翼の天使
  书声琅琅
  学富才高
  取长补短
  废寝忘食
  学究天人
  抬头面对上帝
  笃学不倦
  断织劝学
  力学笃行
  绩学之士
  凿壁借光
  鹦鹉学语
  随遇而安
  发奋图强
  学非所用
  读书三到
  将勤补拙
  万世师表
  曲学阿世
  末学肤受
  孜孜不倦
  一家之学
  青钱学士
  品学兼优
  读书三余
  斗酒学士
  困而不学
  学如不及
  取精用弘
  迎刃而解
  读书破万卷
  顿学累功
  刺股读书
  学步邯郸
  文宗学府
  教然后知困
  以学愈愚
  豁然开朗
  三余读书
  学如登山
  学无常师
  手不释卷
  勤能补拙
  坚持下去
  一丝不苟
  天生我才必有用/
  调嘴学舌
  闻鸡起舞
  曲学行
  好学不倦
  折节读书
  集思广益
  Zai坚强一点
  背水一战
  学贯中西
  循序渐进
  火的信仰叫梦想
  春诵夏弦
  心有阳光
  开卷有益
  奋而斗之
  全神贯注
  守住⒈份猿&
  青藜学士
  熟能生巧
  持之以恒
  学如穿井
  顿学累功
  笃志好学
  似懂非懂
  学以致用
  道学先生
  融会贯通
  古为今用
  学而时习之
  邯郸学步
  笃学好古
  聚精会神
  入主出奴
  博学多闻
  书声琅琅
  孜孜不倦
  学浅才疏
本页面《励志网名四字》的转载信息
本页标题:
本页地址:
转载请以链接标题或地址的形式注明出处,谢谢!
CopyRight 短美文
All Rights Reserved新手园地& & & 硬件问题Linux系统管理Linux网络问题Linux环境编程Linux桌面系统国产LinuxBSD& & & BSD文档中心AIX& & & 新手入门& & & AIX文档中心& & & 资源下载& & & Power高级应用& & & IBM存储AS400Solaris& & & Solaris文档中心HP-UX& & & HP文档中心SCO UNIX& & & SCO文档中心互操作专区IRIXTru64 UNIXMac OS X门户网站运维集群和高可用服务器应用监控和防护虚拟化技术架构设计行业应用和管理服务器及硬件技术& & & 服务器资源下载云计算& & & 云计算文档中心& & & 云计算业界& & & 云计算资源下载存储备份& & & 存储文档中心& & & 存储业界& & & 存储资源下载& & & Symantec技术交流区安全技术网络技术& & & 网络技术文档中心C/C++& & & GUI编程& & & Functional编程内核源码& & & 内核问题移动开发& & & 移动开发技术资料ShellPerlJava& & & Java文档中心PHP& & & php文档中心Python& & & Python文档中心RubyCPU与编译器嵌入式开发驱动开发Web开发VoIP开发技术MySQL& & & MySQL文档中心SybaseOraclePostgreSQLDB2Informix数据仓库与数据挖掘NoSQL技术IT业界新闻与评论IT职业生涯& & & 猎头招聘IT图书与评论& & & CU技术图书大系& & & Linux书友会二手交易下载共享Linux文档专区IT培训与认证& & & 培训交流& & & 认证培训清茶斋投资理财运动地带快乐数码摄影& & & 摄影器材& & & 摄影比赛专区IT爱车族旅游天下站务交流版主会议室博客SNS站务交流区CU活动专区& & & Power活动专区& & & 拍卖交流区频道交流区
论坛徽章:2
OO思想的价值在于
提供一种机制,
这种机制能够把各种数据,以及对数据的操作
分解为正交的操作的集合。
这样同一份代码的迁移性和扩展性就更加强。
所以java.util 以及 STL 里面的东西,都设计成实现很多个接口,
xyfree 发表于
只有OO能做到“数据、操作、正交”这6字吗?
只有OO才具有迁移和扩展吗?
你根本没理解STL的方式, 否则你就不会说出这样的话了。
你去看看STL是如何将容器、迭代器、算法分解为正交化的, boost(的部分组件)又是如何扩展STL的。
java.util? 它具有可比性吗?
STL实现为接口?&&你试过就会知道这有多么难、 多么复杂。
我给你提一个需求: 一个pair的容器, 我需要该容器的迭代器,可以遍历容器, 并且只访问pair的first部分。
你用接口试试?
从此观点来出发,一切皆对象是说:
一个复杂概念必然是由多个简单概念正交组合而成的。
在OO编程语言里面,
一个复杂概念就是一个类,
而那些简单概念就是接口。
某个类的对象,通过继承性,获得接口的特性,
就能够在需要这些接口特性的地方使用,而不管是什么类。
在大多数编程问题中的事物或者概念都可以这样归纳。
所以,一切皆OO没有错。错的是怎样抽象这些概念的人。
xyfree 发表于
由上, OO并不适合所有问题。
所以一切皆OO错了。
呼喊一切皆OO的人, 只能算是迷失在OO井里的蛙而已。
论坛徽章:2
而duck typing, 只依赖需要依赖的, 不做多余的事情。
无论问题领域如何, 你总能逐步演化过去, 而且依然没有多余的东西在里面。
duck typing是直接面向问题的, 而OOP解决问题前要先处理OOP自身带来的问题。
论坛徽章:2
本帖最后由 OwnWaterloo 于
04:01 编辑
你用C++来举例实在不妙,因为可以用宏来消除这个问题,哈哈 XD XD
xyfree 发表于
我不明白:
1. 宏如何消除这个问题?
2. 你指的这个问题, 是什么问题?
关于你的代码: 不是我笨, 而是你根本没有抓出我代码所表达的重点。
我是故意让f0 -& f2的依赖越来越小的。
这是为了说明: OO的设计必须在一个领域内才能做到较好
比如, 在f0的环境下, I0就是一个完美的设计, 你挑不出半点毛病。
而且, 别说你能提前预见到f0之后的环境之类的话, 除非你能保证你能够预见所有的软件需求。
当需求产生变化, 某个算法只需要某个interface功能的子集的时候, 如果要使得设计依然良好, 你就必须重构。
而你在这部分的解释有点混乱, 我没看明白。
iterator只是为了帮助你理解那些符号(仔细看我的原话), 并不是说问题就是这个。
用interface表现ForIt,BiIt,RanIt很简单, 我甚至懒得去写(仔细看我的原话)
我的描述里面直到iterator结束部分, 才只是刚刚开始(仔细看我的原话)。
—— 可惜你偏偏钻到iterator里去了。
我表达的重点在最后一部分, 接口的拆分和组合, 你可以再仔细看一次。
3. 我在描述中提到的一些问题, 你的代码中都有表现:
3.1 ICounter.count
这不算是我在回你的上一贴中提到的问题, 而是在很前面的贴中提到的。
没跑吧? 在OO的熏陶下, 这种代码很容易就从你指尖流出来了。
3.2 接口组合时的命名问题
ILinearStructure & IFifoStructure -& ILinearFIFOStructure
—— 简单的拼接
interface IMyAlgorParam extends IPoppable, IAppendable, IIterable
—— 无意义的名字
IMyAlgorParam我觉得这个名字无论如何也算不上优雅。
你的算法? 你是谁? My这个名字谁都在用。 Param? 这到不是重点。
关键是Algo没能代表任何含义, 什么样的算法?
如果你觉得委屈, 我再问你一个问题以启发你思考:
只需要IIterable和IAppendable的算法, 你叫它什么?
只需要IIterable和IPoppable的算法, 你又叫它什么?
IMyAlgorParam2? IMyAlgorParam3?
这些代码 —— 如我所预言 —— 被你写出来。
你到底是在帮我证明呢, 还是在驳斥我?
而你居然好意思说:“每一个interface都是有意义”的?
你将IMyAlgorParam这种毫无意义的接口暴露给用户, 也好意思说“最后会被隐藏起来” ?
是不是这种狗屎代码闻多了, 你就不觉得臭了?
只有一个方法的接口,本质上是为了更方便地组装类,或者利用现有类的功能。
而且方法数量越少,组装的代价就越少。
怎么到你口中就变成了差劲的设计了....
xyfree 发表于
我没说这是差劲的设计, 这是interface面对极度灵活的需求时不得不做的事。
我的意思是当需求极度灵活时, interface就会演化到只含有单个方法
—— 而这, 其实就是一种带有interface枷锁的duck typing。
不但没有duck typing的优势, 需要去解决interface自身的问题, 比如如何将它们组装起来。
而组装问题 —— 我表达的重点之一 —— 你在回帖中避而不谈 。
你没看懂吧?
所以我说你之前根本就不理解OO的某些优势....
xyfree 发表于
从你的代码里, 我丝毫没有看到OO的优势。 优势在哪? 你说说看?
用GP风格完成同样功能的代码相比, 代码量至少可以缩减到1/3。
GP的优美在于: 仅仅当问题需要依赖什么, 代码才会依赖什么; 没有一丝多余。
而OOP, 有太多工作不是为了问题, 而是为了OOP本身。
你提到的abstLinkedList、absXXX的代码你还没有列出来。
STL就不会有这些bullshit的东西。
事情还没完, 你用java逃避了一个问题: 内存管理。
一旦你在C++里使用interface, 你就不能逃避这个问题。
动态内存分配与虚函数的开销, 一旦使用C/C++, 就不能对效率视而不见。
OO还会影响你的思维, 让你不自觉的就用复杂的方法去解决简单的问题。
比如ICounter, ISorter。
不是我不理解OO的优势, 而是你没看出看出OO的劣势, 以及duck typing如何解决这些问题。
建议你再重新读我那贴的最后部分 —— iterator结束之后。
其实我早就预料到那些枯燥的代码会让人在前半部分就失去耐心, 所以一直懒得写。
虽然你真的是失去耐心, 看见你熟悉的iterface就开搞, 请你再仔细看看后半部分。
如果你真是想学点东西 —— 你受OO的影响也算是深了, 也难怪会为其辩护 —— 而不是上来和我吵架的话。
论坛徽章:2
I'm straight ……
所以我也不懂
论坛徽章:2
恩,的确。这种方式蛮不错的。是C++的实现。只不过用C包装了C++。swig就是这种
模式。但是,说句实话,我不喜欢这种方式,C++太复杂,太容易出错,编译器支持太繁
杂,不容易写出大家都满意的代码。C比较简洁,统一。我觉得用C写内部,做C++的
wrapper很不错的。
starwing83 发表于
就你回复我了, 你再多回复一下最后的问题吧……
这样究竟算是C实现还是C++实现?
我把这种方式再说详细一些:
1. 以C的方式描述模块间的接口
这样就可以避免C++ abi, 以及将繁琐的实现引入客户端
2. 可以为客户端提供一些header-only的C++wrapper。
编译是在客户端产生的, 不存在abi问题。 转发到由C实现的接口。
主要用来弥补C的特性缺失, 比如缺乏重载, 缺乏代码生成器。
3. 实现端想用C就用C, 想用C++就用C++
只要保证不将复杂性跑到模块外便是。
4. 客户端可以是最终代码, 想继续用C就用C, 想用C++就用C++
5. 客户端也可以是另一个客户端的实现段, 也C和C++随意选取, 但必须满足1, 继续以C的方式像新客户提供接口。
论坛徽章:2
template &typename T&
T const& max(list&T& const& li)
& & int mv = li[0];
& & for (int i = 1; i & li.size(); ++i)
& && &&&if (li[ i ] & mv)
& && && && &mv = li[ i ];
哪里用到了两个参数的max函数?
starwing83 发表于
嗯, 这里我说错了, 容器的max需要的是compare。 两元素的max需要的也是compare。
而两个参数的max也有意义,它比这个一般版本的快,而且还方便
starwing83 发表于
这就扯淡了。&对求2个值的max&, 这个版本绝对不会比直接求来得快, 也不会方便。
int i1 = 1212, i2 = 326;
int m1 = max(i1, i2);
std::list&int& l.push_back(1212); l.push_back(326);
int m2 = max(l);
复制代码这就够了。两个参数的这么调用max(1,2);,三个参数的这么调用max(1,2,3);本质上他们
都是列表,于是你可以这么调用:@a = (1,2,3); max @a;这就是我的意思。max根本就是
一个列表上面的操作,把他作为列表操作是很自然的,反而两参数的max只是一个特例,
只是为了优化的目的而去实现的。
starwing83 发表于
这个优化是很重要的。 所以C,C++里, 在确定值的个数, 以及它们并不在容器之中时, 是绝对不会先将值放入容器, 然后求max的。
重复一次, max的例子我举错了。 我现在换成compare可以不?
你继续阐述一下compare是一个object而不是一个procedure?
第一种依赖,实际上是一种实现依赖,是对C++类型系统的一个补丁。实际上It和他的
difference_type是有关系的。这种关系是difference_type是It的一个表现形式。两个类
之间差的类型是什么?如果两匹马比较好坏看哪个地方?是毛色还是身高体重?这显然是
一种组合依赖。组合(或者聚合)是OO的概念之一。两个类之间通过主从的关系产生影响
starwing83 发表于
因为&组合(或者聚合)是OO概念之一&, 所以 &使用了组合(或者聚合)思想就是OO思想&。
发现你的逻辑错误没?&&强盗啊!
&马有毛色和体重概念&。 你也有毛色和体重, 但你显然不是马。
第二种依赖,就是前面说的操作与被操作者的一来,是OO的消息和消息主体的关系(如果
你把method当作对象的话)。
starwing83 发表于
1. 对基本类型 &&& 操作符是没有谁为主体谁为客体之说。
2. 对用户定义类型, &&&操作符可以是1元的, 也可以是2元的。在2元的情况下, 也没有主体客体之说。
就是一个比较过程, 又被你搞出个对象……
同上, 你再继续解释如何将compare理解为一个object而非procedure吧……
第三种依赖,和第一种是一样的,只不过组合的是类型,而不是对象。这个概念你应该很
熟悉,因为在Python里面,类型也是对象。
starwing83 发表于
准确的说法不是&类型也是对象&。
类型T依然是类型T, 只是类型的名字&T&恰好引用了一个类型对象 —— 该对象是另一个类型(假设叫T_type)的实例 —— 该实例包含类型T的一些信息。
真正的类型(如T,T_type)在python里面无法访问也不需要访问。
这样,就在python语言层面伪造出一种&一切都是对象&的假象。
而用C实现python的时候, 类型就是类型, 实例就是实例。
第四种依赖实际上是类的某个组成部分必须满足一个协定。这个协定很显然可以用
interface来写。毋庸置疑它是concept依赖。starwing83 发表于
这协定不能全用interface来写, 理由上面也说了, 比如int*无法实现interface。
其实我还是说错了, 依然可以用interface, 然后为int*实现一个adapter。
但是, 你会这样做吗?
template&class InIt,class F&
F for_each(InIt first, InIt last, F visitor) {
& & for (; first!= ++first) visitor(*first);
& &
}
复制代码这是范型for_each的完整代码。 你用interface试试看?
代码量是它的多少倍? 5倍? 10倍?
还要注意使用interface的效率以及内存管理问题。
他们都能找到OO的影子,方法,类型,乃至于聚合,约定。他们都可以归纳为OO思想的一
个方面。也许这个方面并不合理,也许并不优美,甚至也许过度设计。但是请注意:这只
是想法而已。你其实一个interface都没有写。OO是一种思考方式,在思考完备之前你不
需要动笔。动笔也未必要全都是interface。interface只是一个口头协定:类里面应该有
什么,而不是OO本身。starwing83 发表于
上面说了, 因为有聚合就是OO这个逻辑是不正确的。
综上, 我还是没看到一点OO的影子。
再提一下, 小于操作符, 即使是1元的时候, 我看到的也只是OB而不是OO。
—— 关于偷换概念
为什么我说你在偷换概念?
因为最开始讨论“硬件是否支持OO”这个问题是在52楼。
汇编提供了上层所需要的机制 —— 地址。 通过地址, 可以支持OP(函数指针)和OB(数据指针)
通过汇编能组合出OP和OB是有保证的。
而主流机器上没什么OO一说, OO只是一个软件协议。
而现有的主流OO研究, 是一种限制。 既然是限制, 就肯定有其局限性。
OwnWaterloo 发表于
你说的那些“分页技术类似虚函数”、“IRQ类似多分派”, 无论它们是不是事实, 只要它们不能用来实现语言的虚函数机制,就不是驳斥52楼论点的论据。
除非你能找到例子说明某些语言确实是这样实现虚函数与多分派, 否则你只是在介绍一些事实, 而不是在驳斥观点。
大富大贵, 积分 10355, 距离下一级还需 9645 积分
论坛徽章:0
OO思想的价值在于
提供一种机制,
这种机制能够把各种数据,以及对数据的操作
分解为正交的操作的集合 ...
xyfree 发表于
这六个字我比较赞赏
丰衣足食, 积分 760, 距离下一级还需 240 积分
论坛徽章:0
本帖最后由 xyfree 于
01:46 编辑
回复&&wishel
&&我主要想表达的是现有的OO研究没有考虑多分派情形, 以及现有OO语法不适合表达多分派。
OwnWaterloo 发表于
ReturnType functionName(ParamTypeA p1, ParamTypeB* p2, ParamTypeC& p3, ParamTypeD% p4);
复制代码如果 ParamTypeD% p4 表示的就是多分派呢?
表示的就是使用ParamTypeD 接口的真实类型而不是其引用类型,
这样算不算OO的语法?
丰衣足食, 积分 760, 距离下一级还需 240 积分
论坛徽章:0
本帖最后由 xyfree 于
00:19 编辑
OO思想的价值在于
提供一种机制,
这种机制能够把各种数据,以及对数据的操作
分解为正交的操作的集合。
在使用这些数据的时候,通常不会要求完全利用这些数据提供的全部操作,而只是用其中的若干个,
这时候可以设计这若干个正交操作的接口,来满足具体业务的需要。
这样同一份代码的迁移性和扩展性就更加强。
所以java.util 以及 STL 里面的东西,都设计成实现很多个接口,
以便于适应不同的场合。
从此观点来出发,一切皆对象是说:
一个复杂概念必然是由多个简单概念正交组合而成的。
在OO编程语言里面,
一个复杂概念就是一个类,
而那些简单概念就是接口。
某个类的对象,通过继承性,获得接口的特性,
就能够在需要这些接口特性的地方使用,而不管是什么类。
在大多数编程问题中的事物或者概念都可以这样归纳。
所以,一切皆OO没有错。错的是怎样抽象这些概念的人。
丰衣足食, 积分 760, 距离下一级还需 240 积分
论坛徽章:0
本帖最后由 xyfree 于
01:22 编辑
OwnWaterloo
非常有力漂亮的例子,请原谅我要先开个小玩笑:
你用C++来举例实在不妙,因为可以用宏来消除这个问题,哈哈 XD XD
确实,我从来不否认这个问题的存在,写那些代码确实是很烦人很无聊。
但是, 从工程的角度 来说,那些代码是必须的,而且到最后是 要/会 被隐藏起来的。
不过我不会用这么个答案敷衍你.
我用Java来改写你给出的OO解法的例子,并表达我的意图吧。(至少Java不会有宏这种“卑鄙”的手段)
如果代码有误解或者曲解你的意图,请你指出.
首先是,某个算法对其参数有依赖,这个参数的类型是这样的:interface ILinearStructure {
& & public void iterator();
& & public void append();
& & public void pop()
}
复制代码然后,这个算法的接口是这样的:
interface ICounter {
& & public void count(ILinearStructure p);
}复制代码并且这个算法有这样的实现:
class CounterImpl implements ICounter {
& & public void count(ILinearStructure p) {
& && &&&p.iterator();
& && &&&p.append();
& && &&&p.pop();
& & }
}
复制代码然后我就去为这个算法所依赖的参数的接口,去实现参数的类型:(Java要求把两个类写在不同的文件)
class LinkedList implements ILinearStructure {
& & public void iterator() { /*内容省略*/ }
& & public void append() { /*内容省略*/ }
& & public void pop() { /*内容省略*/ }
}
复制代码
class Vector implements ILinearStructure {
& & public void iterator() { /*内容省略*/ }
& & public void append() { /*内容省略*/ }
& & public void pop() { /*内容省略*/ }
}
复制代码同样地,也有一些本来可以作为 ICounter 参数的,但并没有实现 ILinearStructure 接口的类
class MyStack {
& & public void iterator() { /*内容省略*/ }
& & public void append() { /*内容省略*/ }
& & public void pop() { /*内容省略*/ }
}
复制代码
class MyList {
& & public void iterator() { /*内容省略*/ }
& & public void append() { /*内容省略*/ }
& & public void pop() { /*内容省略*/ }
}
复制代码这时 LinkedList和 Vector 可以为 ICounter 接受,而MyStack 和 MyList&&不可以,因为后二者没有实现 ILinearStructure 接口。
然后,我们希望使用到 MyStack 和 MyList 的功能,并且可以为 ICounter 接受,那么可以这么做。
class MyStack_NowImpl extends MyStack implements ILinearStructure {
& & /* 什么都不用写,因为方法签名是一样的,这在Java里面可行,不知道C++可不可以。
& & ** 如果不一样,那么可以在方法内转型,并且调用ParamA_NoImpl 的方法。
& & **
& & ** 当然,方法多了的话一样很烦。但是在 python 如果同名方法不用转参数类型(我不知道是不是),
& & ** 那是占了动态类型的便宜,而不是duck typing 的优势。
& & ** 而且也会留下更大的麻烦,遇到不可自动转换的或者转换后能运行但是无意义的,崩溃的隐患。
& & */
}
复制代码
class MyList_NowImpl extends MyList implements ILinearStructure {
& & /* 理由同上 */
}
复制代码这样 ICounter 的 count 方法实际上就可以接受MyList、MyStack类型的参数了。
若干天以后,我又写了一个新的算法,它是与先前的算法(即ICounter或者CounterImpl相关的,但它对参数的依赖更小(这说明它根本就是ILinearStructure或者什么的子类,而不是父类!)
这时候,怎样设计这个模型,这就要看与之前的算法是怎样个相关法了。并不是非重构不可的。
譬如新算法只须用到两个方法,但我已经在注意到有ILinearStructure之前 (事实上这简直就是愚蠢,不看manual的后果,你设计一个相关的算法居然不看manual?),
已经为自己的算法设计新的能够接受的参数类型:
interface IFifoStructure {
& & public void iterator();
& & public void pop();
}
复制代码而你的新版算法这样写:
class Reverser {
& & public void reverse(IFifoStructure p);
}
复制代码那么你可以再加入一个抽象类,使你的数据结构能放入旧版算法和新版算法:
interface ILinearFIFOStructure extends IFifoStructure, ILinearStructure {
& & /* 同样是什么都不用加 */
}
复制代码原先的 LinkedList 和 Vector,按照新的需求,应该也是一个 ILinearFIFOStructure 的对象。
这时候有三种做法:
1.&&把原来的 LinkedList 和 Vector 改为抽象类(最好也改名,例如改为 abstLinkedList ,abstVector ),
& &&&然后设计新的类继承abstLinkedList 和 abstVector,并实现IFifoStructure接口(实际上就是在声明那里改一下)
& &&&命名为 LinkedList 和 Vector。
2.&&把LinkedList 和 Vector 的 implements ILinearStructure 改为 implements ILinearFIFOStructure 。
如果LinkedList和Vector是第三方的,不能改的(那你为什么不直接利用这个非要自己写呢???)
3.&&直接继承LinkedList和Vector, 并实现IFifoStructure接口。有隐患,但起码可以解决问题。
这三样都很方便,不需要改动任何业务逻辑部分的源代码。
所以,只要你一开始的建模时对的,设计的扩展性足够好,很少需要大规模重构。再加上 Spring的IoC容器,小改动简直可以忽略。
接下来无论我设计什么新的算法,只要是一个 ILinearFIFOStructure 能够提供的功能,一样跑得顺溜溜的。
按照你的需求,依赖越来越小,所需方法越来越少,一个ILinearFIFOStructure已经足够了。
所以你说的那些很繁琐无趣的代码根本不需要出现,我觉得是你对OO的理解有误,或者是太教条。
如果你实在太笨,在写新算法的时候,又没注意到有&&ILinearFIFOStructure 这个已经是自己写的东西:
class Sorter {
& & public void sort(MyFiloStructure p);
}
复制代码甚至这次笨得掉渣了,不是声明接口,而是定义了一个类:
class MyFiloStructure {
& & public void filoPop();
}
复制代码OO还是为你提供了很方便的、又相对安全的解救办法。(幸好不是C++,不然你没写 virtual 的话就没救了)
想要把之前的数据接口也放进去,例如 ILinearFIFOStructure 的子类,不难,不过要写更多的关于MyFiloStructure业务逻辑代码(谁叫你笨呢?将勤补拙吧)。
class MoreFiloStructure extends MyFiloStructure implements ILinearFiloStructure {
& & public void pop() { filoPop(); }
& & public void append() {};
& & public void iterator() {};
}
复制代码当需求变化到这个地步并且代码那么笨的时候,重构才可是变得值得考虑。
重构并不是那么一件随随便便的事情。
就算你说,用单方法接口,也没有你说的问题,甚至可能解决得更加好看。
我还是按照你的需求那样,提供线性容器的几个常见方法。
如有需要,Object可替换成泛型
interface IIterable {
& & public Object getIterator();
}
复制代码
interface IPoppable {
& & public Object pop();
}
复制代码
interface IAppendable {
& & public void append(Object obj);
}
复制代码
interface ISummable {
& & public int summary();
}
复制代码然后我已经定义了若干容器,它没有实现以上的任意一个接口,或者有的实现了
class ContainerA {
& & public void containerFunc1();
& & public void containerFunc2();
}
复制代码
class ContainerB implements ISummable {
& & public void containerFunc1();
& & public void containerFunc2();
& & public int summary();
}
复制代码如果你的算法需要用到什么功能,用到其中的一个,或者两个,甚至三个接口
譬如 我现在有一个算法,里面会对 ContainerA 执行 pop,append,和getIterator的操作。
只要 ContainerA 实际上支持这些操作(可能只是方法签名不一样),例如这些类似的功能其实是
containerFunc1, containerFunc2()
那你可以写这样一个类:
class MyContainerA extends ContainerA implements IPoppable, IAppendable, IIterable {
& & public Object pop() { containerFunc1(); }
& & public void append(Object obj) { containerFunc2();&&}
& & public Object getIterator() {&&/*代码略*/&&}
}
复制代码如果我要对ContainerB 进行一些操作,但我用不上 summary 方法,需要重构吗?
class MyContainerB extends ContainerB
& && &&&implements IPoppable, IAppendable, IIterable {
& & public Object pop() { /*代码略*/ }
& & public void append(Object obj) {&&/*代码略*/&&}
& & public Object getIterator() {&&/*代码略*/&&}
}
复制代码然后你的算法的参数需要什么操作,你就声明实现什么接口
interface IMyAlgorParam extends IPoppable, IAppendable, IIterable {
}
复制代码你的算法代码这样写
class MyAlgor {
& & public void doAlgor(IMyAlgorParam p);
}
复制代码这样会很麻烦吗?
每一个interface都是有意义的。
根本就不必使用 duck typing....
只有一个方法的接口,本质上是为了更方便地组装类,或者利用现有类的功能。
而且方法数量越少,组装的代价就越少。
怎么到你口中就变成了差劲的设计了....
所以我说你之前根本就不理解OO的某些优势....
您需要登录后才可以回帖
北京皓辰网域网络信息技术有限公司. 版权所有 京ICP证:060528号 北京市公安局海淀分局网监中心备案编号:
广播电视节目制作经营许可证(京) 字第1234号
中国互联网协会会员&&联系我们:
感谢所有关心和支持过ChinaUnix的朋友们
转载本站内容请注明原作者名及出处}

我要回帖

更多关于 将勤补拙打一生肖 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信