DEV Community

Cover image for Attributes in Object-Oriented Programming Languages and their UML representation (on the Java example)
sharc
sharc

Posted on

Attributes in Object-Oriented Programming Languages and their UML representation (on the Java example)

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

Figure 1. UML Person class and object diagram

Now, attributes are utilized to describe properties of objects.

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

Figure 2. UML representation of Person class with attributes

Figure 3 shows exemplary Java code of a Person class with attributes as described earlier.

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

    // Constructor, getters, setters, and other methods
}
Enter fullscreen mode Exit fullscreen mode
Figure 3. Java code of a Person class with attributes

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

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

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.

Person Mike = new Person("Mike", "Smith", new CustomDate(25, 11, 1990, 6, 35));

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).

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

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

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

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

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

Figure 6. UML representation of a multi-value attribute skills

Such attribute can be implemented using collection as shown below:
List<String> skills = new ArrayList<>();

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);
}
Enter fullscreen mode Exit fullscreen mode

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

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

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

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

Such attribute is denoted with /.

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.

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
}
Enter fullscreen mode Exit fullscreen mode
Figure 9. Java code of a Person class with derives attribute age

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.

Top comments (0)