I’m not sure if this answers your question, but just from the point of view of dispatch you can do things like:
julia> abstract type Layoutable end
julia> struct Axis<:Layoutable
label::String
position::Float64
end
julia> (::Type{T})(figure) where {T<:Layoutable} = T("x", 0.0)
julia> Axis(nothing)
Axis("x", 0.0)
This of course is a silly example, but I imagine something like
function (::Type{T})(figure) where {T<:Layoutable}
# do generic stuff before specific implementation, then
specific_stuff(T, figure)
# do generic stuff after specific implementation
end
And then for every layoutable (e.g. Axis) you just overload specif_stuff(::Type{Axis}, figure).