六個(gè)Android開發(fā)者不可不知的設(shè)計(jì)模式
1 什么是設(shè)計(jì)模式
設(shè)計(jì)模式是一種可以重復(fù)使用的解決軟件工程問題的方案。與許多特定程序的解決方案不同,設(shè)計(jì)模式可以應(yīng)用于許多不同的程序中。設(shè)計(jì)模式不是一個(gè)成品,而是一個(gè)可以應(yīng)用于多種情況并隨時(shí)間改進(jìn)的模板,是非常強(qiáng)大的軟件工程工具。使用經(jīng)過驗(yàn)證的原型可以提高開發(fā)速度,使用設(shè)計(jì)模式模板的開發(fā)人員可以提高編碼效率和最終產(chǎn)品的可讀性。
2 模式#1 ?? 單例模式
單例模式是一種允許創(chuàng)建唯一實(shí)例并訪問該實(shí)例的類。它包含一個(gè)私有的靜態(tài)變量,可以容納該類的唯一實(shí)例。在需要限制類的實(shí)例化為一個(gè)對(duì)象時(shí),單例模式通常很有用。通常在需要協(xié)調(diào)系統(tǒng)中操作的單個(gè)對(duì)象時(shí)使用單例模式。
3 單例類的屬性
- 僅一個(gè)實(shí)例
- 全局可訪問
4 制作單例類的規(guī)則
制作單例類遵循以下規(guī)則:
- 私有構(gòu)造函數(shù)
- 類的靜態(tài)引用
- 一個(gè)靜態(tài)方法
- 全局可訪問的對(duì)象引用
- 多線程一致性
5 單例示例
以下是Java中Singleton類的示例:
public class Singleton {
private static Singleton instance = null;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
以下是Kotlin中Singleton類的示例:
Object Singleton {
init { println("Hello Singleton") }
}
6 模式#2 ?? 工廠模式
工廠模式是一種創(chuàng)建對(duì)象的設(shè)計(jì)模式,其名稱源于其類似于工廠的行為。在工廠模式中,工廠類負(fù)責(zé)控制對(duì)象的實(shí)例化邏輯。當(dāng)需要?jiǎng)?chuàng)建多個(gè)具有相似行為的對(duì)象時(shí),工廠模式非常有用。您可以使用工廠模式來創(chuàng)建對(duì)象,而無(wú)需指定具體的類。這使代碼更加靈活,進(jìn)行修改和維護(hù)變得更輕松。
請(qǐng)看以下代碼以便更好地理解:
interface Currency {
fun symbol(): String
fun code(): String
}
enum class Country {
UnitedState, Spain
}
class USDollar : Currency {
override fun symbol(): String {
return "$"
}
override fun code(): String {
return "USD"
}
}
class Euro : Currency {
override fun symbol(): String {
return "€"
}
override fun code(): String {
return "EUR"
}
}
object CurrencyFactory {
fun currency(country: Country): Currency {
return when (country) {
Country.UnitedState -> {
USDollar()
}
Country.Spain -> {
Euro()
}
}
}
}
7 模式#3 ?? 建造者模式
建造者模式旨在“將復(fù)雜對(duì)象的構(gòu)建與其表示分離,以便相同的構(gòu)建過程可以創(chuàng)建不同的表示形式。”它用于逐步構(gòu)建復(fù)雜對(duì)象,最后一步將返回對(duì)象。
8 制作Builder類的規(guī)則
制作Builder類遵循以下規(guī)則:
- 私有構(gòu)造函數(shù)
- 通常稱為Builder的內(nèi)部類
- 每個(gè)字段的函數(shù)設(shè)置字段值返回
- 構(gòu)建函數(shù)返回Main類的實(shí)例
以下是Kotlin中Builder類的示例:
class Hamburger private constructor(
val cheese: Boolean,
val beef: Boolean,
val onions: Boolean
) {
class Builder {
private var cheese: Boolean = true
private var beef: Boolean = true
private var onions: Boolean = true
fun cheese(value: Boolean) = apply { cheese = value }
fun beef(value: Boolean) = apply { beef = value }
fun onions(value: Boolean) = apply { onions = value }
fun build() = Hamburger(cheese, beef, onions)
}
}
9 模式#4 ?? 外觀模式
外觀模式提供一個(gè)更高級(jí)的接口,使一組其他接口更容易使用。它封裝了一組類的復(fù)雜性,并提供了一個(gè)更高級(jí)別的接口,以簡(jiǎn)化對(duì)這些類的訪問。以下圖表更清楚地說明了這個(gè)想法。
interface BooksApi {
@GET("books")
fun listBooks(): Call<List<Book>>
}
Square的Retrofit是一種開源的安卓庫(kù),可幫助您實(shí)現(xiàn)外觀模式。您可以創(chuàng)建一個(gè)接口,為客戶端提供API數(shù)據(jù)。
10 模式#5 ?? 依賴注入
依賴注入就像搬進(jìn)一間家具齊全的公寓一樣,您需要的一切都已經(jīng)在那里,不必等待家具送貨或遵循家具公司的指令指南來組裝它。
在軟件方面,依賴注入要求您提供任何所需的對(duì)象來實(shí)例化新對(duì)象。這個(gè)新對(duì)象不需要自己構(gòu)建或自定義對(duì)象。
在安卓中,您可能會(huì)發(fā)現(xiàn)需要從應(yīng)用程序的各個(gè)點(diǎn)訪問同一復(fù)雜對(duì)象,例如網(wǎng)絡(luò)客戶端、圖像加載器或用于本地存儲(chǔ)的SharedPreferences
。為了方便訪問這些對(duì)象,您可以將它們注入到活動(dòng)和片段中,并直接使用它們。這種方式稱為依賴注入,它允許您在應(yīng)用程序中更容易地管理和共享對(duì)象,并提高了代碼的可重用性和測(cè)試可靠性。
以下示例展示了一個(gè)沒有使用依賴注入的Car
類的代碼。在該示例中,Car
類正在構(gòu)建自己的Engine
依賴項(xiàng):
class Car {
private val engine = Engine()
fun start() {
engine.start()
}
}
fun main(args: Array) {
val car = Car()
car.start()
}
這種做法存在問題,因?yàn)?code style="background-color: rgb(231, 243, 237); padding: 1px 3px; border-radius: 4px; overflow-wrap: break-word; text-indent: 0px; display: inline-block;">Car類對(duì)Engine
類有硬編碼的依賴關(guān)系,這將導(dǎo)致代碼難以維護(hù)和測(cè)試。如果需要更改Engine
實(shí)現(xiàn)或使用不同的實(shí)現(xiàn),則需要修改Car
類的代碼。這可能會(huì)導(dǎo)致代碼的重構(gòu)和重新測(cè)試,并且可能會(huì)影響其他依賴于Car
類的代碼。因此,使用依賴注入可以解決這個(gè)問題,并提高代碼的可重用性和可測(cè)試性。
使用依賴注入的代碼是什么樣子?代替每個(gè)Car
實(shí)例在初始化時(shí)構(gòu)建自己的Engine
對(duì)象,它在構(gòu)造函數(shù)中作為參數(shù)接收一個(gè)Engine
對(duì)象:
class Car(private val engine: Engine) {
fun start() {
engine.start()
}
}
fun main(args: Array) {
val engine = Engine()
val car = Car(engine)
car.start()
}
11 模式#6 ?? 適配器模式
適配器模式是一種用于連接兩個(gè)不兼容接口之間的橋梁模式。
這種模式涉及一個(gè)單一的類,該類負(fù)責(zé)連接獨(dú)立或不兼容接口的功能?,F(xiàn)實(shí)生活中的一個(gè)例子可能是一個(gè)讀卡器,它充當(dāng)內(nèi)存卡和筆記本電腦之間的適配器。您將記憶卡插入讀卡器,將讀卡器插入筆記本電腦,以便可以通過筆記本電腦讀取記憶卡。