Attributes in Object-Oriented Programming Languages and their UML representation (on the Java example)
Tags: uml, java, oop, programming
Published: 2024-02-11 12:28:17

## OOP and its importance 📚
Object-Oriented Programming (OOP) is a programming paradigm based on the concept of "objects". It may be helpful for mirroring real-world in code. Similar to some paradigms in web development like MVC patterns, OOP may be useful as it provides a clear modular structure for programs and is often the choice for when complex systems are being implemented.

Additionally, the systems that are to be implemented with OOP language can be very well modelled using UML (Unified Modeling Language) which consists of many OOP design patterns and is universally used in systems documentation and modelling stage.

Having that in mind, let's understand some key concepts of OOP.

## Attributes, classes, objects... 🔍
A short and simple introduction of the vocabulary may be necessary here.

> A class in Object-Oriented Programming (OOP) is a named description of a group of objects which share the same set of properties.

A class describes an object eg. a Person class describes properties that a Person object may have like firstName, lastName and dateOfBirth.

> Objects are instances of a given class. Objects are described by specifying properties (attributes) available in the class.

An object of a Person class can be created as:

`Person Mike = new Person("Mike", "Smith", LocalDate.of(1990, 11, 25));`

Figure 1 presents UML class and object diagrams (single entity diagrams) with simple attributes as described earlier.

![UML Person class and object diagrams](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4tw7uv1t2de6iaafn194.png)<center>Figure 1. UML Person class and object diagram</center><br>Now, attributes are utilized to describe properties of objects.
<br>
> Attributes represent the state or characteristics of an object and are defined within a class.

## Different kinds of attributes 📊

In OOP, especially in Java, there are different kinds of attributes, each serving a unique purpose:

1. Simple
2. Complex
3. Mandatory
4. Optional
5. Single
6. Multi-valued
7. Class attribute
8. Derived

Let's explore what are the differences, how we can use these attributes in programming and how to represent them in UML?

## Simple attribute
Simple attribute holds basic and straightforward data about the object. Simple attribute typically refers to a basic data type that is not composed of more complex structures. It is usually described by a primitive data type like an integer, float or boolean.

As shown on Figure 2, Person class can be described using 2 simple attributes - firstName and lastName.
Strings are considered a simple attribute when they hold basic values like a person name and are not composed of more complex structures. However, strings are not primitive data types because they represent objects of class String.

![UML representation of Person class with attributes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2s6jzk05kteidtfgo3zi.png)<center>Figure 2. UML representation of Person class with attributes</center><br>Figure 3 shows exemplary Java code of a Person class with attributes as described earlier.<br>
```
public class Person {
    private String firstName; // Simple attribute
    private String lastName; // Simple attribute
    private LocalDate dateOfBirth; // Complex attribute

    // Constructor, getters, setters, and other methods
}
```<center>Figure 3. Java code of a Person class with attributes</center><br>

## Complex attribute
Complex attribute is described using another class. In a business class (eg. Person class) we store a reference to the object of that auxiliary class rather than a value.

Figure 4 shows UML representation of Person class with a complex attribute of CustomDate for dateOfBirth attribute.

![UML representation of Person class with a complex attribute of CustomDate](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yn40pp088h33w86i4umd.png)<center>Figure 4. UML representation of Person class with a complex attribute of CustomDate</center><br>Just using LocalDate class from standard Java package is enough to make complex attribute. However, the goal here is to understand and be able to model and create various attributes so we can actually create our own CustomDate class and use it for the Person object as shown below.<br><br>`Person Mike = new Person("Mike", "Smith", new CustomDate(25, 11, 1990, 6, 35));`<br><br>Complex attribute contains two or more fields as a whole, inextricably linked with the object that owns it (not to be confused with an association).<br><br>

## Optional attribute
Its value may be unknown at the time the object was created. With that in mind An appropriate type must be used that allows null assignment. Simple types (such as int or double) do not satisfy this requirement unless wrappers are used (eg. Integer for int, Double for double etc.).

The setter method accepts a null value as a parameter but still a not-null value may have certain constraints upon it. In such a case, an appropriate check should be made when setting a new value and, if necessary, an exception signaling a validation error should be thrown.

Figure 5 shows UML representation of Person class with an optional attribute of secondName.

![UML representation of Person class with an optional attribute of secondName](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2bnhz30ves10younqewm.png)<center>Figure 5. UML representation of Person class with an optional attribute of secondName</center><br>For complex attributes we can store a null as an information about lack of value. For simple attributes, wrappers are a good solution.

Another possibility is to use Optional (Java 8+), but there are some problems, e.g. serialization. When using frameworks on top of Java like Spring Boot, annotation of @Nullable is possible.

## Mandatory attribute
Any non-optional attribute is mandatory. It must be of value throughout the life of the object. Usually, an empty string is not allowed either.

To prevent null values from being set for numeric types a simple type (eg. int, double) can be used. For object types (eg. String or custom class), it is necessary to make an appropriate validation of the value in the setter method and, if necessary, throw an exception in the case of setting an incorrect value.

Figure 6 shows UML representation of Person class with mandatory attribute of socialSecurity number.

![UML representation of Person class with mandatory attribute of socialSecurity number](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d0jpv32kxch7gpecv2hc.png)<center>Figure 6. UML representation of Person class with mandatory attribute of socialSecurity number</center><br>

## Multi-value attribute
May contain more than one value. Implemented with a collection (more often) or an array (in special cases). If the mandatory attribute is also multi-valued then it should always have at least one value - when removing elements from the collection make sure to check if there is at least one element left (eg. isEmpty() method on ArrayList)

Figure 6 shows UML representation of a multi-value attribute skills that could be implemented with an ArrayList of Strings.

![UML representation of a multi-value attribute skills](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uo4kpz7bnrlowsjso91n.png)<center>Figure 6. UML representation of a multi-value attribute skills</center><br>Such attribute can be implemented using collection as shown below:
`List<String> skills = new ArrayList<>();`<br>
When adding, you need to check if the value passed is correct (e.g. if it is not null, empty string, number out of range, etc.).

The method that gets the attribute must be secured against unauthorized modification of the collection:

```
public List<String> getSkills() {
    return Collections.unmodifiableList(courses);
}
```

## Class attribute
Contains values common to all objects of a given class. Its value can be modified as long as there are no additional constraints.

Figure 7 shows UML representation of Person class with class attribute of country.

![UML representation of Person class with class attribute of country](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dooay7hj3ptg05aw7uwp.png)<center>Figure 7. UML representation of Person class with class attribute of country</center><br>Such attribute is denoted with underline. Similarly to class method, which is also denoted with underline.

Class attribute is not initialized for a single object but rather is present for all object of a given class. Hence, the 'static' keyword - it static fields cannot be treated like objects.

Static field can also be initialized with the static setter method, but it is not a common practice. Usually, it is initialized on declaration.

`private static String country = "US";`

## Derived attribute
Its value is calculated on the basis of other data (other attributes, associations, etc.).

Figure 8 shows UML representation of derived attribute age in Person class.

![UML representation of derived attribute age in Person class](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v164quwlwx2w8jyvuoc3.png)<center>Figure 8. UML representation of derived attribute age in Person class</center><br>Such attribute is denoted with /.<br><br>Moreover, this attribute is not declared as a class field but rather is derived from other attributes (as stated by its definition) as shown on Figure 9.<br>

```
import java.time.LocalDate;
import java.time.Period;

public class Person {
    private String firstName; // Simple attribute
    private String lastName; // Simple attribute
    private LocalDate dateOfBirth; // Complex attribute

    // Constructor
    public Person(String firstName, String lastName, LocalDate dateOfBirth) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.dateOfBirth = dateOfBirth;
    }
    
    // Derived attribute: age
    public int getAge() {
        return Period.between(this.dateOfBirth, LocalDate.now()).getYears();
    }

    // getters, setters, and other methods
}
```<center>Figure 9. Java code of a Person class with derives attribute age</center><br>

## Conclusion 🤔
Attributes constitute the basis of classes and objects which themselves lay in the core of Object-Oriented Programming. Understanding them is the first step towards well-modelled and implemented code. However, complex system is rich in many more components such as associations, constraints and a very important **inheritance**. Knowing the details of these will be a topic for a future writing.