Sobes.tech
Middle

Gde ste koristili generike u svom iskustvu razvoja?

sobes.tech АИ

Одговор од АИ

Opšte korišćeni generici:

  • Za implementaciju tip-bezbednih kolekcija. Na primer, ArrayList<MyObject> umesto sirovog ArrayList, što sprečava greške tokom izvršavanja povezane sa konverzijom tipova.
    // Nije tip-bezbed pristup (sirovi tip)
    List list = new ArrayList();
    list.add("Red");
    list.add(123); // Dodavanje int
    
    // Tip-bezbed pristup sa generičkim tipovima
    List<String> stringList = new ArrayList<>();
    stringList.add("Red");
    // stringList.add(123); // Kompajler će prikazati grešku
    
    
  • Za kreiranje univerzalnih adaptera za RecyclerView. Omogućava ponovno korišćenje logike adaptera za različite tipove podataka.
    // Primer univerzalnog ViewHolder-a
    class GenericViewHolder<T>(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun bind(item: T) {
            // Logika za povezivanje podataka u zavisnosti od tipa T
        }
    }
    
    // Primer univerzalnog adaptera
    class GenericAdapter<T>(private val items: List<T>) : RecyclerView.Adapter<GenericViewHolder<T>>() {
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GenericViewHolder<T> {
            // Kreiranje ViewHolder-a
        }
    
        override fun onBindViewHolder(holder: GenericViewHolder<T>, position: Int) {
            holder.bind(items[position])
        }
    
        override fun getItemCount() = items.size
    }
    
  • Za kreiranje fabričkih funkcija za objekte. Za dobijanje konkretnog tipa objekta bez eksplicitnog prebacivanja.
    interface Factory<T> {
        T create();
    }
    
    class StringFactory : Factory<String> {
        override fun create(): String {
            return "Novi red";
        }
    }
    
    class IntegerFactory : Factory<Int> {
        override fun create(): Int {
            return 100;
        }
    }
    
    Factory<String> stringFactory = StringFactory();
    val myString: String = stringFactory.create(); // Dobijamo String bez prebacivanja
    
  • Za ograničavanje tipova u metodama i klasama. Korišćenje ograničenih generičkih tipova (<T extends MyInterface> ili <T super MyClass>) za garantovanje da generički tip implementira određeni interfejs ili nasleđuje od određene klase.
    // Metod koji prihvata listu elemenata koji implementiraju interfejs Serializable
    public <T extends Serializable> void saveObjectList(List<T> list) {
        // Logika za čuvanje
    }
    
  • U arhitektonskim komponentama. Na primer, pri radu sa LiveData ili ViewModel, često se koriste generički tipovi za definisanje tipa podataka kojima upravljaju.
    // LiveData za listu objekata određenog tipa
    val myData: LiveData<List<MyItem>> = // inicijalizacija
    
    // ViewModel sa podacima određenog tipa
    class MyViewModel : ViewModel() {
        val data: MutableLiveData<MyStateType> by lazy {
            MutableLiveData<MyStateType>()
        }
    }
    
  • Pri razvoju mrežnih klijenata. Za automatsku deserializaciju odgovora sa servera u konkretne tipove objekata.
    // Primer Retrofit servisa sa generičkim u odgovoru
    interface ApiService {
        @GET("users")
        Call<List<User>> getUsers();
    
        @GET("products/{id}")
        Call<Product> getProduct(@Path("id") String productId);
    }
    

Generici su značajno povećali tip-bezbednost, čitljivost i mogućnost ponovne upotrebe koda.