作者godfat (godfat 真常)
看板java
标题Re: [问题] 想请问interface的具体意义
时间Fri Jan 26 16:14:14 2007
※ 引述《H45 (!H45)》之铭言:
: 使用装饰者的角度来看更显得怪异
: 因为Decorator Pattern是动态地将责任加诸於物件上
: 但是Square似乎没什麽更多的责任可以加诸在Rectangle上
: Square只是一种长和宽相等的Rectangle罢了
: 提不上是Rectangle的什麽装饰者
: 所以我认为用装饰者的角度来看,只是让事情更复杂化而已
其实我也觉得用 decorator 会让问题变得更加模糊难懂
回头来看 Square 和 Rectangle, 这两个东东会想怎麽操作他们?
令 Rectangle 有 setWidth 和 setHeight,
那 Square 呢?同样都有这两个操作吗?
那麽为了防止失去 Square 的特性,是否要这样实作 setWidth?
public void setWidth(int num){
this.do_set_width_height(num);
}
public void setHeight(int num){
this.do_set_width_height(num);
}
private void do_set_width_height(int num){
this.width_ = this.height_ = num;
}
不知道这样做有没有意义?如果 setWidth 和 setHeight 实际上做的事
根本就完全一样。假使增加这两个 method 纯粹只是为了和 Rectangle
有相似的介面,那试问,当你呼叫 setWidth 时,你会想得到 height 其实也变了?
假若让 setWidth 就单纯只是 setWidth, 那是否又违反了 Square 的前提?
丢 exception 不成?其实这同样违反了 LSP, 因为原本并不会有 exception.
个人认为,Square 和 Rectangle 之间不应存在太多关系
令 abstract class Shape{...}
则 class Rectangle extends Shape{...}
与 class Square extends Shape{...}
觉得这样比较合理一些
Rectangle 提供 setWidth 与 setHeight, 甚至 setWidthHeight(int, int);
Square 仅提供 setWidthHegiht(int) 或 setSize or whatever you like
总之他们的操作介面是不一样的,因为他们的特徵会影响到其操作介面
硬要让他们有共通介面的话,就很容易出现预期外的行为
那如果 Rectangle 和 Square 之间其实有共用的程式码怎麽办?
提供一个类似 pimpl 的东西给他们共同使用即可
http://en.wikipedia.org/wiki/Opaque_pointer
这边就不针对名词做解释了,我不知道 Java 怎麽形容这种做法
写成程式码大概是这样:
class Rectangle_Stuff_Implement{ // 加底线看起来比较清楚,字型关系
protected Rectangle_Stuff_Implement(){...} // 只给 Rect 和 Square 用
protected void draw(int width, int height){...}
...
}
class Rectangle extends Shape{
private Rectangle_Stuff_Implement imp_ = new Rectangle_Stuff_Implement();
public void draw(){ imp_.draw(this.width_, this.height_); }
...
}
class Square extends Shape{
private Rectangle_Stuff_Implement imp_ = new Rectangle_Stuff_Implement();
public void draw(){ imp_.draw(this.length_, this.length_); }
...
}
诸如此类
不过理所当然,考虑实作前,先要想的是问题到底是什麽(problem domain)
在这个 thread 中,有人提到不是所有的车都有雨刷,
雨刷怎麽可以当汽车与机车的共同属性?
呃,我想说除非我们是在做模拟现实世界的程式,
不然,说不定他想解决的问题里,所有的汽车机车都有雨刷呢?
在游戏程式中,确实很可能会有这种事情发生,毕竟本来就不是在模拟现实
这也是为什麽我说为什麽物件导向可以被违反,更别提现实世界了
重点是问题是什麽,是不是会有这个状况出现
一股脑把现实世界放进来考虑,常常只会造成不必要的复杂性
就好像上面的例子里,也许我们根本就不在乎 Rectangle 的长宽到底是什麽
反正他就只是一种形状嘛,说不定根本没有外界可以操作的 setWidth 与 setHeight
那麽让这两者之间有着继承关系,也不见得是那麽坏的事
或是直到我们有一天发现,确实是需要 setWidth 与 setHeight 的介面
那麽这时候,就很有可能得改变设计,把 Square 与 Rectangle 的继承关系解除
我觉得有些话说得很好,需求会慢慢压迫你寻求好的设计,此时好的设计就会慢慢浮现。
design pattern 也不是忽然出现的,他们是长时间在程式设计领域慢慢累积下来的,
不是谁忽然发明这麽伟大的设计,而是自然而然,我们就会想到这些解决办法可以解决
某个很复杂的问题。但是当问题本身并没有那麽复杂时,过度的设计也只是找自己麻烦
而已。
可以参考一下 Martin Fowler 的文章,Is Design Dead?
http://www.martinfowler.com/articles/designDead.html
Martin Fowler 是不少知名书籍的作者,
如 Refactoring, UML Distilled, Analysis Patterns 等
--
『风车』が廻り続ける度に 『美しき』幻想が静かに纺がれ
『焔』の揺らめきの外に 『腕』を伸ばす愚かな者达 -《Roman》5th Story
『宝石』をより多く掴もうと 『朝と夜』の狭间を彷徨い続ける Track 10
『星屑』の砂の煌めきにも 『葡萄酒』の仄甘い陶酔を魅せ 黄昏の贤者
『贤者』が忌避する槛の中から 『伝言』の真意を彼等に问うだろう
『天使』が别れを告げし时 『地平线』は第五の物语を识る
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 220.135.28.18