字幕列表 影片播放
(upbeat music)
(歡快的音樂)
- [Eric] The dependency and version principle
- [Eric] 依賴性和版本原則
gives us guidance to not design our high-level modules
給我們的指導是,不要設計我們的高級模塊
to depend on our low-level modules,
依賴於我們的低級模塊。
but that sounds counterintuitive,
但這聽起來是反直覺的。
because it advises us to think about designs
因為它建議我們思考設計問題
in a manner that's really the opposite
以一種真正相反的方式
of what we're used to.
的我們所習慣的。
We're used to thinking about designs
我們習慣於思考設計問題
as top-down decompositions.
作為自上而下的分解。
We take a problem and we factor it
我們把一個問題和我們的因素
into a high-level set of components
變成一套高層次的組件
that depend on a lower level set of components.
這取決於較低層次的組件集。
We often think of the high-level components
我們經常想到的是高層組件
as some kind of policymakers
作為某種政策制定者
that are commanding a set of low-level components
這是在指揮一組低級別的組件
who are really carrying out all the real work.
哪些人真正在進行所有真正的工作。
The problem with this approach
這種方法的問題在於
is that it typically tightly couples
是,它通常是緊緊地結合在一起
our high-level components to our low-level ones.
我們的高級別組件與我們的低級別組件之間的關係。
A symptom of this tight coupling
這種緊密耦合的一個症狀是
is that it's often difficult to take
是,它往往很難採取
that high-level component and then to go reuse it
該高級組件,然後去重新使用它
with the totally different underlying implementation
與完全不同的底層實現
of the low-level components.
的低級組件。
If our design is right,
如果我們的設計是正確的。
that's something we really should be able to do.
這是我們真的應該能夠做到的。
The dependency inversion principle
依賴性反轉原則
tells us to think of this in a different way,
告訴我們要以不同的方式來思考這個問題。
by reversing the direction of this dependency.
通過扭轉這種依賴關係的方向。
It tells us really two things.
它實際上告訴我們兩件事。
First, as we've said, high-level modules
首先,正如我們已經說過的,高級別模塊
should not depend on low-level modules,
不應依賴低級別的模塊。
actually both should depend on abstractions.
實際上,這兩者都應該依賴於抽象的東西。
And second, the principal offers that abstractions
其次,校長提出,抽象的東西
should not depend on details,
不應依賴細節。
actually details should depend on abstractions.
實際上,細節應該取決於抽象的東西。
Both of these statements require some explanation.
這兩種說法都需要一些解釋。
Let's take a look at an example.
我們來看看一個例子。
Consider this remote control class.
考慮到這個遠程控制類。
It has a click method that's called one user indicates
它有一個點擊方法,被稱為一個用戶表示
they want to control a television.
他們想控制一臺電視。
The remote control depends
遙控器取決於
on a lower level class call television,
在一個較低的級別上調用電視。
and that class offers two methods,
而該類提供了兩種方法。
turn TV on and turn TV off.
開啟電視和關閉電視。
So when the user clicks,
是以,當用戶點擊。
the remote control click method has the logic to toggle
遙控器的點擊方法有邏輯,可以切換
between the on and off states by calling the turn TV on
通過調用 "打開電視",在打開和關閉狀態之間進行切換。
and turn TV off methods respectively.
和關閉電視的方法分別。
So this design looks straightforward enough,
是以,這個設計看起來足夠簡單明瞭。
but there is room for improvement.
但仍有改進的餘地。
For starters, this remote control controls only televisions
對於初學者來說,這個遙控器只能控制電視
and more specifically the television represented
更確切地說,是以電視為代表的
by the concrete television class.
由具體的電視類。
What if we want to control another kind of television
如果我們想控制另一種電視呢?
or even another kind of device with an on-off switch?
甚至是另一種有開關的設備?
It's not hard to notice that we have a high level component,
不難發現,我們有一個高層次的組成部分。
our remote control depending directly
我們的遠程控制直接取決於
on a low-level component,
在一個低級別的組件上。
the concrete television class.
具體的電視類。
So according to our principal, that can't be good.
所以根據我們的校長,這不可能是好事。
But how else would we approach this?
但是,我們還能如何處理這個問題呢?
Let's think through what the high level policy
讓我們想一想,高水平的政策是什麼?
for this design should be.
這個設計的目的應該是。
What's the high level policy?
高級別的政策是什麼?
Well as Robert Martin,
好比羅伯特-馬丁。
the originator of this principle says,
這一原則的提出者說。
"It's the abstraction that underlies the application."
"它是支撐應用的抽象概念"。
So, how's this for an improved high-level policy
那麼,這樣一個改進的高層政策如何呢?
or abstraction, or remote control
或抽象化,或遠程控制
that can control anything with an on off button,
可以控制任何有開、關按鈕的東西。
a TV, a light, a sprinkler system, and so on.
一臺電視、一盞燈、一個灑水系統,等等。
Let's express that in our class diagram.
讓我們用我們的類圖來表達。
To do that,
要做到這一點。
we're going to create an abstraction for an on-off device.
我們將為一個開關設備創建一個抽象的概念。
More specifically, we're going to create an interface
更具體地說,我們將創建一個接口
on off device that supports two methods,
在關閉的設備上,支持兩種方法。
turn on and turn off.
開啟和關閉。
Next, we'll have our remote control
接下來,我們將有我們的遙控器
depend on that abstraction by composing our remote control
通過組成我們的遠程控制來依賴這一抽象概念。
with an on-off device.
有一個開關裝置。
And remember before the remote control dependent
還記得在遙控器依賴之前
on a concrete type, that television class.
在一個具體的類型上,即電視類。
So, now a remote control no longer depends
是以,現在遙控器不再取決於
on a low level class.
在一個低級別的班級。
Instead, it actually depends on an abstraction
相反,它實際上取決於一個抽象概念
that's that on off device interface.
這就是那個開關設備接口。
This goes the other way too
這也是另一種情況
remember that our principal also tells us
記住,我們的校長也告訴我們
that abstractions should not depend on details,
抽象的東西不應該依賴於細節。
rather details should depend on abstractions.
相反,細節應該取決於抽象的東西。
Well, let's examine the television class now
好吧,我們現在來研究一下電視類的問題
and notice first that it implements
並首先注意到,它實現了
the on-off device interface,
開-關設備接口。
no longer does it expose its proprietary turn TV on
它不再暴露其專有的打開電視的功能。
and turn TV off methods.
和關閉電視的方法。
So rather than our abstraction, the on-off device,
是以,而不是我們的抽象概念,即開關設備。
depending on the low level details of the television,
取決於電視的低水平細節。
that is it's turned TV on and turn TV off methods,
那就是它的打開電視和關閉電視的方法。
it is the television that is depending
是電視的作用
on the high level of abstraction,
在高度抽象的層面上。
that is the turn on and turn off methods
這就是開啟和關閉的方法
in the on off device interface.
在開-關設備界面。
So this is often the reverse of how we think of design,
所以這往往與我們對設計的思考方式相反。
but by adhering to the dependency and version principle,
但通過遵守依賴性和版本原則。
we really free our high-level components
我們真正釋放了我們的高級組件
from being dependent on the details of low-level components.
不依賴於低級組件的細節。
This really helps us avoid rigidity,
這確實有助於我們避免僵化。
fragility and immobility.
脆弱和不流動。
The dependency in version principle
版本原則中的依賴性
tells us that all relationships between components
告訴我們,組件之間的所有關係
shouldn't involve abstract classes and interfaces,
不應該涉及抽象類和接口。
not concrete classes, in doing so helps us design software
而不是具體的類,這樣做是為了幫助我們設計軟件
that's reusable and resilient to change,
可重複使用並對變化有彈性。
because these abstractions allow the details
因為這些抽象的東西允許細節
between the components to remain isolated from each other.
組件之間保持相互隔離。