W3Cschool
恭喜您成為首批注冊(cè)用戶(hù)
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
到目前為止,我們定義了關(guān)于布局元素類(lèi)的一個(gè)層次結(jié)構(gòu)。你可以把包含這個(gè)層次關(guān)系的類(lèi)作為 API 接口提供給其它應(yīng)用,但有時(shí)你可以希望對(duì)函數(shù)庫(kù)的用戶(hù)隱藏這種層次關(guān)系,這通??梢允褂?factory(構(gòu)造工廠)對(duì)象來(lái)實(shí)現(xiàn)。一個(gè) factory 對(duì)象定義了用來(lái)構(gòu)造其它對(duì)象的函數(shù)。庫(kù)函數(shù)的用戶(hù)可以通過(guò)工廠對(duì)象來(lái)構(gòu)造新對(duì)象,而不需要通過(guò)類(lèi)的構(gòu)造函數(shù)來(lái)創(chuàng)建類(lèi)的實(shí)例。使用工廠對(duì)象的好處是,可以統(tǒng)一創(chuàng)建對(duì)象的接口并且隱藏被創(chuàng)建對(duì)象具體是如何來(lái)表示的。這種隱藏可以使得你創(chuàng)建的函數(shù)庫(kù)使用變得更簡(jiǎn)單和易于理解,也正是隱藏部分實(shí)現(xiàn)細(xì)節(jié),可以使你有機(jī)會(huì)修改庫(kù)的實(shí)現(xiàn)而不至于影響庫(kù)的接口。
實(shí)現(xiàn) factory 對(duì)象的一個(gè)基本方法是采用 singleton 模式,在 Scala 中,可以使用類(lèi)的伴隨對(duì)象(companion 對(duì)象)來(lái)實(shí)現(xiàn)。比如:
object Element {
def elem(contents: Array[String]):Element =
new ArrayElement(contents)
def elem(chr:Char, width:Int, height:Int) :Element =
new UniformElement(chr,width,height)
def elem(line:String) :Element =
new LineElement(line)
}
我們先把之前 Element 的實(shí)現(xiàn)列在這里:
abstract class Element {
def contents: Array[String]
def height: Int = contents.length
def width: Int = if (height == 0) 0 else contents(0).length
def above(that: Element) :Element =
new ArrayElement(this.contents ++ that.contents)
def beside(that: Element) :Element = {
new ArrayElement(
for(
(line1,line2) <- this.contents zip that.contents
) yield line1+line2
)
}
override def toString = contents mkString "\n"
}
有了 object Element(類(lèi) Element 的伴隨對(duì)象),我們可以利用 Element 對(duì)象提供的 factory 方法,重新實(shí)現(xiàn)類(lèi) Element 的一些方法:
abstract class Element {
def contents: Array[String]
def height: Int = contents.length
def width: Int = if (height == 0) 0 else contents(0).length
def above(that: Element) :Element =
Element.elem(this.contents ++ that.contents)
def beside(that: Element) :Element = {
Element.elem(
for(
(line1,line2) <- this.contents zip that.contents
) yield line1+line2
)
}
override def toString = contents mkString "\n"
}
這里我們重寫(xiě)了 above 和 beside 方法,使用伴隨對(duì)象的 factory 方法 Element.elem 替代 new 構(gòu)造函數(shù)。
這樣修改之后,庫(kù)函數(shù)的用戶(hù)不要了解 Element 的繼承關(guān)系,甚至不需要知道類(lèi) ArrayElement,LineElement 定義的存在,為了避免用戶(hù)直接使用 ArrayElement 或 LineElement 的構(gòu)造函數(shù)來(lái)構(gòu)造類(lèi)的實(shí)例,因此我們可以把 ArrayElement,UniformElement 和 LineElement 定義為私有,定義私有可以也可以把它們定義在類(lèi) Element 內(nèi)部(嵌套類(lèi))。下面為這種方法的使用:
object Element {
private class ArrayElement(val contents: Array[String])
extends Element {
}
private class LineElement(s:String) extends ArrayElement(Array(s)) {
override def width = s.length
override def height = 1
}
private class UniformElement (ch :Char,
override val width:Int,
override val height:Int
) extends Element{
private val line=ch.toString * width
def contents = Array.fill(height)(line)
}
def elem(contents: Array[String]):Element =
new ArrayElement(contents)
def elem(chr:Char, width:Int, height:Int) :Element =
new UniformElement(chr,width,height)
def elem(line:String) :Element =
new LineElement(line)
}
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話(huà):173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: