Using interface traits

Occasionally, you may encounter a situation where you need to determine whether a data type implements an interface. The information about whether a data type exhibits certain behavior is also called a trait.

How do we implement traits for an interface? In the Vehicle module, we can add a new function, as follows:

# trait
has_wheels(vehicle) = error("Not implemented.")

This default implementation simply raises an error, and that's intentional. This trait function is expected to be implemented by any vehicle data types. In the interface code, the landing function can make use of the trait function for a more refined logic:

# Landing (using trait)
function land2!(vehicle)
has_wheels(vehicle) && engage_wheels!(vehicle)
println("Landing vehicle: ", vehicle)
end

Generally speaking, trait functions just need to return a binary answer, true or false; however, it is entirely up to the developer how to design the trait. For example, it is perfectly reasonable to define the trait function so that it returns the type of landing gear—:wheels, :slider, or :none.

It is a good idea to define traits as simply as possible. As you may recall, the interface that we implemented for our fighter jet in the previous section requires five functions—power_on!, power_off!, move!, turn!, and position. From a design perspective, we can create different traits:

  • has_power(): returns true if the vehicle needs to be powered on/off
  • can_move(): returns true if the vehicle is able to move
  • can_turn(): returns true if the vehicle can turn in any direction
  • location_aware(): returns true if the vehicle can keep track of its location

Once we have these small building blocks, we can define more complex traits that are composed of these simple ones. For example, we can define a trait called smart_vehicle that supports all of the four traits that we listed. In addition, we can define a solar_vehicle trait, which is used for vehicles that rely on solar power and is always on.

Using traits is a very powerful technique to model object behaviors. There are some patterns that are built around how to implement traits in practice. We will discuss these more extensively in Chapter 5, Reusability Patterns.

At this point, you should feel more comfortable about designing interfaces in Julia. They are relatively simple to understand and develop. While Julia does not provide any formal syntax for interface specification, it is not difficult to come up with our own convention. With the help of traits, we can even implement more dynamic behavior for our objects. 

We have now concluded all topics in this chapter.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.85.33