کلاس های داده در کاتلین

هرچند زبان خوب رو JVM کم نیست اما از وقتی گوگل از کاتلین رو آندروید به صورت صد درصد پشتیبانی کرد به این زبان خیلی بیشتر توجه میشه و انصافن شایسته این توجه هم هست. این زبان به گونه ای طراحی شده که بتونه رو پلتفرم های دیگه ای مثل جاوا اسکریپت و ناتیو هم اجرا بشه. یکی از قشنگترین ویژگی هاش تعامل خیلی خیلی خوب باجاواست به صورتی که میتونی هرجای پروژه که دلت خواست جاوا بزنی و هرجا دلت خواست کاتلین بنویسی و باهم ارتباط هم داشته باشن. مثلا یک کلاس رو با جاوا بنویسی و یه کلاسی رو با کاتلین بعد از اونا به یک شکل استفاده کنی.

یکی از مسایلی که زبان جاوا به نسبت زبانهای مدرن تر داره حجم خیلی زیاد کد بویلرپلیت یا همون کدهایی که تا حد زبادی تکراریه و مجبوری بنویسی و همه جا هم تکرار کنی. کاتلین این مساله رو خیلی خوب به نظرم حل کرده. یکی از نمونه هاش کلاس های داده ایه.

معمولا تو زبان های استاتیک چون همه چی به نحوی باید زمان کامپایل مشخص باشه و درصد زیادی از خطایابی زمان کامپایل انجام میشه — برخلاف زبان های دینامیک که بخش زیادی از این فرایند زمان اجرا مدیریت میشه — شما باید هر نوع داده ای که استفاده میکنید رو کاملا تعریف کنید. مثلا مدل داده ها یا اشیایی که برای انتقال بین لایه های مختلف استفاده میشن و اونارو دی تی او میگن مثال مشخصیه که خیلی هم پرکاربرده و زیاد استفاده میشه. این کلاس رو در نظر بگیرید

import java.util.Objects;

public class UserDto {
private String firstName;
private String lastName;
private int age;
private double salary;
private String image;


public UserDto(String firstName, String lastName, int age, double salary, String image) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.salary = salary;
this.image = image;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public double getSalary() {
return salary;
}

public void setSalary(double salary) {
this.salary = salary;
}

public String getImage() {
return image;
}

public void setImage(String image) {
this.image = image;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserDto userDto = (UserDto) o;
return age == userDto.age &&
Double.compare(userDto.salary, salary) == 0 &&
Objects.equals(firstName, userDto.firstName) &&
Objects.equals(lastName, userDto.lastName) &&
Objects.equals(image, userDto.image);
}

@Override
public int hashCode() {

return Objects.hash(firstName, lastName, age, salary, image);
}

@Override
public String toString() {
return "UserDto{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", age=" + age +
", salary=" + salary +
", image='" + image + '\'' +
'}';
}
}

این همه کد ابدا قرار نیست کار خفنی بکنه و فقط قرار یه کلاس باشه که بشه دی تی او و ما بتونیم داده های از این نوع رو بین لایه های مختلف و یا توابع و متدهای برنامه پاس بدیم. معادل این کلاس تو کاتلین همین خط پایینه :)

data class UserDto(var firstName: String, var lastName: String, var age: Int, var salary: Double, var image: String?)

نکته کلیدی استفاده از کلمه کلیدی data است. این کلمه میگه این کلاس من قراره یک کلاس داده ای باشه و خودش هرچی که لازمه تولید میکنه واسش.این چیزایی که لازمه ایناست:

متدهای /toString/hashCode/equals

متدی که برای استخراج خصوصیت های کلاس تحت یک متغیر استفاده میشه — componentN

متد کپی

یه سری نکات رو هم باید در استفاده از این نوع کلاس ها مد نظر داشته باشید که تو مستندات خودش توضیح داد

https://kotlinlang.org/docs/reference/data-classes.html