2

I have implemented the following UML in Kotlin, and I am now considering whether I should explicitly implement the methods getName(), getAddress(), and setAddress() in my code, as they are mentioned in the UML. I know that Kotlin provides implicit generation of getters and setters for class properties.

Since getName(), getAddress(), and setAddress() methods don't have any additional logic, I considered using implicit getters and setters provided by Kotlin. However, since these methods are explicitly mentioned in the UML, I am unsure whether I should proceed with the implicit generation or explicitly implement them in my code.

Should i explicitly implement these methods or continue using the implicit getters and setters provided by Kotlin?

enter image description here

For more details, this is my Kotlin class based on the UML that I have implemented using the implicit getter and setter provided by Kotlin.

class Student(val name: String, var address: String) {

    private var numCourses: Int = 0

    private val courses: Array<String> = Array(MAX_COURSES) { "" }

    private val grades: IntArray = IntArray(MAX_COURSES)
    companion object {
        const val MAX_COURSES = 30
    }

    fun printGrades() {
        print(name)
        for (i in 0 until numCourses) {
            print(" ${courses[i]}:${grades[i]}, ")
        }
        println()
    }

    fun calculateAverageGrade() = grades.sum().toDouble() / grades.size

    fun addCourseGrade(course: String, grade: Int) {

        require(numCourses < MAX_COURSES) {
            "A student cannot take more than $MAX_COURSES courses"
        }

        require(grade in 0..100) {
            "Grade must be between 0 and 100"
        }

        courses[numCourses] = course
        grades[numCourses] = grade
        numCourses++
    }

    override fun toString() = "name($address)"

}
Sweeper
  • 213,210
  • 22
  • 193
  • 313
Ali Dehkhodaei
  • 426
  • 3
  • 15
  • It would be extremely against Kotlin convention and it would be deliberately writing more convoluted and long-winded code. I guess the question is, why did the person write this UML with syntax that looks like Kotlin but is so anti-Kotlin? If it was written as language-agnostic, I would interpret it as a guideline and that the getters/setters should be implemented as properties in languages that support them. – Tenfour04 Jul 15 '23 at 12:09
  • By the way, shouldn’t it be `require(numCourses <= MAX_COURSES)`? – Tenfour04 Jul 15 '23 at 12:11
  • @Tenfour04 No, it is correct. when it is `numCourses > MAX_COURSES`, it throw exception. – Ali Dehkhodaei Jul 15 '23 at 12:23
  • @Tenfour04 Is this what you mean? UML is not correct or not designed for Kotlin? – Ali Dehkhodaei Jul 15 '23 at 12:28
  • Your code will crash if `numCourses` is the same as `MAX_COURSES` which is contrary to the behavior I would expect based on the property and constant names. – Tenfour04 Jul 15 '23 at 14:59
  • @Tenfour04 Are you sure? I was test it before. – Ali Dehkhodaei Jul 15 '23 at 15:31
  • Oh, I see, you inaccurately named the variable. `numCourses` doesn't represent the number of courses. It represents the current course index, which can be zero for a valid course. – Tenfour04 Jul 15 '23 at 16:08
  • @Tenfour04 Every instance can have 30 course and numCources is zero when a instance created. – Ali Dehkhodaei Jul 15 '23 at 16:22

1 Answers1

1

If your ultimate goal is to write good Kotlin code, and is just using the UML diagram as a guide, then do not declare your getters and setters. That is not idiomatic. I would compare that to naming your functions in_snake_case.

If someone (who perhaps is not familiar with Kotlin's conventions) gave you this UML diagram and asked you to implement it, and that "someone" is later going to depend on your code having a method called getName (and so on), then writing your own getName could be considered. Though, it is better if you can tell that person about Kotlin's idioms first :) Note that this isn't a problem if that person writes in Java.

Also note that if you are using Kotlin/JVM, you cannot directly declare your own getters/setters for a public property:

// this does not compile:
class Student(val name: String) {
    fun getName() = name
}

This is because getName is also the name used for the JVM method name of the implicitly generated getter. You would need to use @JvmName to give it some other name. private properties don't have a private JVM getter generated (but I cannot find documentation on this), so you can also fix this by making the property private.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • This uml designed by me. is it not correct for Kotlin classes? – Ali Dehkhodaei Jul 15 '23 at 16:45
  • @AliDehkhodaei oops, I added `private` accidentally. As for the UML, I think it is correct if you, and whoever is reading it, understand Kotlin’s conventions, i.e. understands that getters and setters are implicit. After all, UML is just a way of communication. If you get the message across, then everything is fine. – Sweeper Jul 16 '23 at 00:28
  • Please review my question as I have made improvements to it. – Ali Dehkhodaei Jul 16 '23 at 08:13
  • @AliDehkhodaei Please do not edit your question so drastically that it becomes a different question. You should post a new question. That said, I feel your new question could be considered a little opinion based. – Sweeper Jul 16 '23 at 08:16
  • I am sorry, I created a new question. https://stackoverflow.com/questions/76697310/which-uml-diagram-is-correct-for-this-kotlin-class – Ali Dehkhodaei Jul 16 '23 at 08:23