Sobes.tech
Middle

Kde ste vo svojej vývojárskej skúsenosti použili generické typy?

sobes.tech AI

Odpoveď od AI

Všeobecne používané generiká:

  • Na implementáciu typovo bezpečných kolekcií. Napríklad, ArrayList<MyObject> namiesto surového ArrayList, čo zabraňuje chybám počas behu spojeným s konverziou typov.
    // Nesprávny prístup (surový typ)
    List list = new ArrayList();
    list.add("Riadok");
    list.add(123); // Pridanie int
    
    // Typovo bezpečný prístup s generikami
    List<String> stringList = new ArrayList<>();
    stringList.add("Riadok");
    // stringList.add(123); // Kompilátor hlási chybu
    
    
  • Na tvorbu univerzálnych adaptérov pre RecyclerView. Umožňuje opätovné použitie logiky adaptéra pre rôzne typy dát.
    // Príklad univerzálneho ViewHolderu
    class GenericViewHolder<T>(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun bind(item: T) {
            // Logika viazania dát podľa typu T
        }
    }
    
    // Príklad univerzálneho adaptéra
    class GenericAdapter<T>(private val items: List<T>) : RecyclerView.Adapter<GenericViewHolder<T>>() {
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GenericViewHolder<T> {
            // Vytvorenie ViewHolderu
        }
    
        override fun onBindViewHolder(holder: GenericViewHolder<T>, position: Int) {
            holder.bind(items[position])
        }
    
        override fun getItemCount() = items.size
    }
    
  • Na tvorbu tovární pre objekty. Na získanie konkrétneho typu objektu bez explicitnej konverzie.
    interface Factory<T> {
        T create();
    }
    
    class StringFactory : Factory<String> {
        override fun create(): String {
            return "Nový riadok";
        }
    }
    
    class IntegerFactory : Factory<Int> {
        override fun create(): Int {
            return 100;
        }
    }
    
    Factory<String> stringFactory = StringFactory();
    val myString: String = stringFactory.create(); // Získavame String bez konverzie
    
  • Na obmedzenie typov v metódach a triedach. Použitie obmedzených generík (<T extends MyInterface> alebo <T super MyClass>) na zabezpečenie, že typ generika implementuje určitú rozhranie alebo dedí od určitej triedy.
    // Metóda, ktorá prijíma zoznam prvkov implementujúcich rozhranie Serializable
    public <T extends Serializable> void saveObjectList(List<T> list) {
        // Logika uloženia
    }
    
  • V architektonických komponentoch. Napríklad pri práci s LiveData alebo ViewModel, často sa používajú generiká na určenie typu dát, ktorými spravujú.
    // LiveData pre zoznam objektov určitého typu
    val myData: LiveData<List<MyItem>> = // inicializácia
    
    // ViewModel s dátami určitého typu
    class MyViewModel : ViewModel() {
        val data: MutableLiveData<MyStateType> by lazy {
            MutableLiveData<MyStateType>()
        }
    }
    
  • Pri vývoji sieťových klientov. Pre automatickú deserializáciu odpovedí zo servera do konkrétnych typov objektov.
    // Príklad Retrofit služby s generikom v odpovedi
    interface ApiService {
        @GET("users")
        Call<List<User>> getUsers();
    
        @GET("products/{id}")
        Call<Product> getProduct(@Path("id") String productId);
    }
    

Generiká výrazne zvýšili typovú bezpečnosť, čitateľnosť a možnosť opätovného použitia kódu.