Sobes.tech
Middle

Unde ați folosit generice în experiența dvs. de dezvoltare?

sobes.tech AI

Răspuns de la AI

Utilizarea generics:

  • Pentru implementarea colecțiilor sigure în ceea ce privește tipul. De exemplu, ArrayList<MyObject> în loc de ArrayList brut, ceea ce previne erorile la timpul de execuție legate de conversia tipurilor.
    // Abordare nesigură în ceea ce privește tipul (tip brut)
    List list = new ArrayList();
    list.add("String");
    list.add(123); // Adăugăm int
    
    // Abordare sigură cu generice
    List<String> stringList = new ArrayList<>();
    stringList.add("String");
    // stringList.add(123); // Compilatorul va da eroare
    
  • Pentru crearea de adaptoare universale pentru RecyclerView. Permite reutilizarea logicii adaptorului pentru diferite tipuri de date.
    // Exemplu de ViewHolder universal
    class GenericViewHolder<T>(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun bind(item: T) {
            // Logica de legare a datelor în funcție de tipul T
        }
    }
    
    // Exemplu de adaptor universal
    class GenericAdapter<T>(private val items: List<T>) : RecyclerView.Adapter<GenericViewHolder<T>>() {
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GenericViewHolder<T> {
            // Crearea ViewHolder
        }
    
        override fun onBindViewHolder(holder: GenericViewHolder<T>, position: Int) {
            holder.bind(items[position])
        }
    
        override fun getItemCount() = items.size
    }
    
  • Pentru crearea fabricilor de obiecte. Pentru a obține un tip specific de obiect fără conversie explicită.
    interface Factory<T> {
        T create();
    }
    
    class StringFactory implements Factory<String> {
        @Override
        public String create() {
            return "Șir nou";
        }
    }
    
    class IntegerFactory implements Factory<Integer> {
        @Override
        public Integer create() {
            return 100;
        }
    }
    
    Factory<String> stringFactory = new StringFactory();
    String myString = stringFactory.create(); // Obține un String fără conversie
    
  • Pentru restricționarea tipurilor în metode și clase. Utilizarea generics restricționate (<T extends MyInterface> sau <T super MyClass>) pentru a garanta că tipul generic implementează o anumită interfață sau moștenește o anumită clasă.
    // Metodă care acceptă o listă de elemente care implementează Serializable
    public <T extends Serializable> void saveObjectList(List<T> list) {
        // Logica de salvare
    }
    
  • În componentele arhitecturale. De exemplu, atunci când lucrați cu LiveData sau ViewModel, generics sunt adesea folosite pentru a defini tipul de date pe care le gestionează.
    // LiveData pentru o listă de obiecte de un anumit tip
    val myData: LiveData<List<MyItem>> = // inițializare
    
    // ViewModel cu date de un anumit tip
    class MyViewModel : ViewModel() {
        val data: MutableLiveData<MyStateType> by lazy {
            MutableLiveData<MyStateType>()
        }
    }
    
  • La dezvoltarea clienților de rețea. Pentru deserializarea automată a răspunsurilor de la server în obiecte de un anumit tip.
    // Exemplu de serviciu Retrofit cu generics în răspuns
    interface ApiService {
        @GET("users")
        Call<List<User>> getUsers();
    
        @GET("products/{id}")
        Call<Product> getProduct(@Path("id") String productId);
    }
    

Generics au crescut semnificativ siguranța tipurilor, lizibilitatea și reutilizarea codului.