Value based dispatch with a string presents some challenges. If you use a Symbol, an interned string, directly, then value based dispatch can be made very efficient due to constant propagation. julia> @btime ValueFruitFactory .fruit (: orange ) 1.424 ns (0 allocations: 0 bytes ) Main . ValueFruitFactory .Orange () julia> f () = ValueFruitFactory .fruit (: orange ) f (generic function with 1 method ) julia> @btime f () 1.423 ns (0 allocations: 0 bytes ) Main . ValueFruitFactory .Orange () julia> @code_typed f () CodeInfo ( 1 ─ return $ (QuoteNode( Main . ValueFruitFactory .Orange () )) ) => Main . ValueFruitFactory .Orange Compare the typed code with the string version. julia > @code_typed g() CodeInfo( 1 ─ % 1 = $(Expr(:foreigncall, :(:jl_string_ptr), Ptr{UInt8}, svec(Any), 0 , :(:ccall), "orange" ))::Ptr{UInt8} │ % 2 = Core.sizeof( "orange" )::Int64 │ % 3 = $(Expr(:foreigncall, :(:jl_symbol_n), Ref{Symbol}, svec(Ptr{UInt8}, Int64), 0 , :(:ccall), :( % 1 ), :( % 2 ), "orange" ))::Symbol │ % 4 = invoke Main.ValueFruitFactory.fruit( % 3 ::Symbol)::Union{Main.ValueFruitFactory.Apple, Main.ValueFruitFactory.Orange} └── return % 4 ) = > Union{Main.ValueFruitFactory.Apple, Main.ValueFruitFactory.Orange}