Kotlinプロジェクト開発プラクティス2

一緒に書く習慣をつけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加して3日目です。クリックしてイベントの詳細をご覧ください

1.シングルトン実装の3つの方法

  • object

最初にコードを見てください:

object Pro {
}
复制代码

Proのシングルトンを実現するのはとても簡単です。それをJavaコードに逆コンパイルして、特定の実装原理を確認できます。

public final class Pro {
   @NotNull
   public static final Pro INSTANCE;

   private Pro() {
   }

   static {
      Pro var0 = new Pro();
      INSTANCE = var0;
   }
}
复制代码

まずPro、クラスのコンストラクターがとして宣言されprivateます。次に、これが静的コードブロックによって実装されたシングルトンであることがわかります。クラスの静的コードブロックが1回だけ実行されるという機能を使用して、クラスはに属します线程安全且饿汉式。 ;

Javaでは、Pro.INSTANCEこのシングルトンが取得されますが、kotlinは直接Proシングルトンを取得します

  • lazy

最初のコード:

class Pro private constructor() {
    companion object {
        val INSTANCE by lazy {
            Pro()
        }
    }
}
复制代码

これは主に、コンパニオンオブジェクトによって静的変数として宣言されたプロパティを使用し、lazyのデフォルトの実装モードはロックスレッドセーフです。これは线程安全且懒汉式シングルトン実装です。詳細については、Kotlin開発プラクティスの1つlazyを参照してください。

  • ダブルチェックロック

上記のコード:

@Volatile
var singleton: Pro? = null

fun getInstance(): Pro {
    if (singleton == null) {
        synchronized(Pro::class.java) {
            if (singleton == null) {
                singleton = Pro()
            }
        }
    }
    return singleton!!
}
复制代码

上記は、Javaダブルチェックロックのkotlin実装です。ここで:

  1. @Volatileコード命令の順序を保証する
  2. getInstance初期化が完了していることを確認するために、メソッドの内層と外層はsingletonsingletonであり、スレッドはロックを競合する必要はありません。
  3. getInstanceメソッドの内層はsingleton空であり、前のスレッドが初期化されている場合singleton、後続のスレッドが再度初期化されないようにします。

ご覧のとおり、これは线程安全且懒汉式ある意味で実装されたシングルトンです。

2.typealias複合型のエイリアスを取得します

このtypealiasキーワードは、主にタイプにエイリアスを与えるために使用されます。次の2つの使用シナリオを以下に説明します。

  • 関数型エイリアス

日常の開発では、次のような関数型を一般的に使用する必要があります。

//拼接Int和String类型并返回String类型
val block: ((Int, String) -> String)? = null
复制代码

この関数型(Int, String) -> String)は書くのが面倒で読みにくいので、今度はtypealias次のものをアップロードします。

typealias Concat = (Int, String) -> String
val block: Concat? = null
复制代码

(Int, String) -> String)使い勝手が良いだけでなくConcat、この関数タイプの使用シナリオを簡単に確認できます。スプライシング

  • 簡略化された汎用パス

を使用する場合ViewModel、インターフェイスの戻り値を次のようにカプセル化することがよくあります。

class MainViewModel: ViewModel() {
    val data: MutableLiveData<Response<String>> = MutableLiveData()
    
    fun test() {
        data.value = Response("haha")
    }
    
    data class Response<T>(val data: T? = null)
}
复制代码

Responseサーバーの戻り値をカプセル化するために使用されるジェネリック型Tは、応答データを逆シリアル化できるエンティティークラスを表します。

上記のように、各定義はジェネリック型MutableLiveData宣言する必要があります。これは、すべてのインターフェイス応答の統一されたカプセル化であり、明確な型であり、その中の型は動的に指定する必要がある型であるためです。作成された時間。Response<T>ResponseResponse<T>TMutableLiveData

省略できますか?Response<T>アップロードする時が来ましたResponsetypealias

typealias ExternalLiveData<T> = MutableLiveData<MainViewModel.Response<T>>
复制代码

したがって、作成するたびMutableLiveDataに、次のように記述できます。

val data1: ExternalLiveData<String> = MutableLiveData()
复制代码

おすすめ

転載: juejin.im/post/7082560219615592456