設計模式是咱們Android成長之路必備的一項技能,相信不少同窗都已經Get了,如今讓咱們來看看在Kotlin中設計模式是如何表達的呢。java
單例模式是一種經常使用的軟件設計模式。在它的核心結構中只包含一個被稱爲單例的特殊類。經過單例模式能夠保證系統中一個類只有一個實例 。
使用場景: 確保某個類有且只有一個對象的場景,避免產生多個對象消耗過多的資源。設計模式
public class Singleton{
private volatile static Singleton sInstance;
private Singleton() {}
public static Singleton getInstance() {
if (sInstance == null) {
synchronized (Singleton.class) {
if (sInstance == null) {
sInstance = new Singleton();
}
}
}
return sInstance;
}
}
複製代碼
餓漢式:安全
public class Singleton {
public static Singleton getInstance() {
return SingletonInstance.sInstance;
}
private static class SingletonInstance {
private static final Singleton sInstance = new Singleton();
}
}
複製代碼
object Singleton {
}
複製代碼
kotlin寫法是否是簡單直接越看越喜歡,一句話就歸納了。
來看一下官方的說明bash
Singleton may be useful in several cases, and Kotlin (after Scala) makes it easy to declare singletons, This is called an object declaration, and it always has a name following the object keyword.Object declaration's initialization is thread-safe.app
在 Kotlin 當中直接經過關鍵字 object 聲明一個單例,而且它是線程安全的,而且object 聲明的方式也是延遲加載的。ide
代理模式是爲其餘對象提供一種代理以控制對這個對象的訪問學習
代理模式是使用一個代理對象來訪問目標對象的行爲,Kotlin 下的實現與 Java 基本相似ui
抽象類this
abstract class Notify(var context: Context) {
var notificationManager: NotificationManager? = null
var builder: NotificationCompat.Builder? = null
init {
notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager
builder = NotificationCompat.Builder(context)
builder?.apply {
setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(PendingIntent.getActivity(context, 0,
Intent(context, NotifyActivity::class.java),
PendingIntent.FLAG_UPDATE_CURRENT))
}
}
/**
* 發送一條通知
*/
abstract fun send()
/**
* 取消一條通知
*/
abstract fun cancel()
}
複製代碼
被代理類spa
class NotifyNormal(context: Context) : Notify(context) {
override fun send() {
builder?.let {
it.setContent(RemoteViews(context.packageName, R.layout.layout_notify_normal))
val notification = it.build()
notificationManager?.notify(0, notification)
}
}
override fun cancel() {
notificationManager?.cancel(0)
}
}
複製代碼
class NotifyBig(context: Context) : Notify(context) {
override fun send() {
builder?.let {
it.setContent(RemoteViews(context.packageName, R.layout.layout_notify_normal))
it.setCustomBigContentView(RemoteViews(context.packageName, R.layout.layout_notify_normal))
val notification = it.build()
notificationManager?.notify(0, notification)
}
}
override fun cancel() {
notificationManager?.cancel(0)
}
}
複製代碼
class NotifyHeadersUp(context: Context) : Notify(context) {
override fun send() {
builder?.let {
it.setContent(RemoteViews(context.packageName, R.layout.layout_notify_normal))
it.setCustomBigContentView(RemoteViews(context.packageName, R.layout.layout_notify_normal))
it.setCustomHeadsUpContentView(RemoteViews(context.packageName, R.layout.layout_notify_normal))
val notification = it.build()
notificationManager?.notify(0, notification)
}
}
override fun cancel() {
notificationManager?.cancel(0)
}
}
複製代碼
代理類
class NotifyProxy(context: Context) : Notify(context) {
private var notify: Notify? = null
init {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
notify = NotifyHeadersUp(context)
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
notify = NotifyBig(context)
} else {
notify = NotifyNormal(context)
}
}
override fun send() {
notify?.send()
}
override fun cancel() {
notify?.cancel()
}
}
複製代碼
調用
NotifyProxy(this@MainActivity).send()
複製代碼
經過代理模式能夠把複雜的判斷和生成通知的邏輯都屏蔽了,讓代碼更加清晰
建造者模式是將一個複雜對象的構建和它的表示分離,使得一樣的構建過程能夠建立不一樣的表示
好比咱們經常使用的 AlertDialog 、universal-image-loader就是使用的建造者模式,讓咱們看看kotlin中該怎麼表達
class Dog private constructor(builder: Builder) {
internal var name: String? = null
init {
name = builder.name
}
class Builder {
internal var name: String? = null
fun name(name1: String): Builder {
name = name1
return this
}
fun build(): Dog {
return Dog(this)
}
}
}
複製代碼
使用方法與Java同樣
Dog.Builder().name("旺財").build()
複製代碼
其實Kotlin 的 apply 擴展原生也支持 Builder 模式
class Cat {
var name: String = "miaomiao"
var age = 0
}
複製代碼
Cat().apply {
name = "momo"
age = 1
}
複製代碼
觀察者模式是定義對象間的一種一對多的依賴關係,使得每當一個對象改變狀態,則全部依賴於它的對象都會獲得通知並被自動更新
常見的觀察者模式如RecyclerView的Adapter的notifyDataSetChanged更新方法、BroadcastReceiver、開源庫EventBus、RxJava等等
Kotlin的寫法與Java相似
經過UnReadMessageObserver 單例來實現全局觀察管理未讀消息
object UnReadMessageObserver {
private var map = mutableMapOf<String, UnReadMessageListener>()
fun addUnReadMessageListener(listenerKey: String, listener: UnReadMessageListener) {
map[listenerKey] = listener
}
fun updateUnReadMessage(count: Int) {
map.forEach {
it.value.updataUnReadMessage(count)
}
}
fun removeUnReadMessageListener(listenerKey: String) {
if (map.containsKey(listenerKey)) {
map.remove(listenerKey)
}
}
}
interface UnReadMessageListener {
fun updataUnReadMessage(unReadCount: Int)
}
複製代碼
被觀察者
UnReadMessageObserver.updateUnReadMessage(1)
複製代碼
觀察者
UnReadMessageObserver.addUnReadMessageListener(MainActivity::class.java.name, object : UnReadMessageListener {
override fun updataUnReadMessage(unReadCount: Int) {
Toast.makeText(this@MainActivity, "count:$unReadCount", Toast.LENGTH_SHORT).show()
}
})
複製代碼
觀察者模式是咱們常常使用的模式,它的一個重要做用就是解耦,將觀察者個被觀察者解耦
適配器模式把一種接口變換成客戶端所期待的另外一種接口,從而使本來因接口不匹配而沒法在一塊兒工做的兩個類可以在一塊兒工做
舉個栗子:手機普通充電須要5V的電壓,而生活用電電壓是220V,而咱們的充電器就充當了轉換適配的做用,
這裏的適配器也是一個道理
適配器模式中的目標接口也就是 5V電壓的接口
interface VoltageFive {
fun Voltage5(): Int
}
複製代碼
適配器模式中須要被適配的接口,平常220V電壓
class VoltageDaily {
fun Voltage220(): Int {
return 220
}
}
複製代碼
適配器
class VoltageAdapter(var voltageDaily: VoltageDaily) : VoltageFive {
override fun Voltage5(): Int {
return 5
}
fun getVoltage220(): Int {
return voltageDaily.Voltage220()
}
}
複製代碼
以上就是適配器模式在Kotlin上的簡單實現了,適配器模式的原理在於把本來不兼容的接口融合在了一塊兒,使之能更好的協做。
以上幾種設計模式是咱們常常會用到的,Kotlin的大多設計模式基本與Java實現大體相同,靈活的使用設計模式能讓咱們代碼更加的靈活,便於管理。本次學習就到這了,同窗們下次再見。