The factory method pattern

The idea of the factory method pattern is to provide a single interface to create different types of objects that conform to an interface while hiding the actual implementation from the client. This abstraction decouples the client from the underlying implementation of the feature provider.

For example, a program might need to format some numbers in the output. In Julia, we might want to use the Printf package to format numbers, as follows:

Perhaps we do not want to couple with the Printf package because we want to switch and use a different formatting package in the future. In order to make the application more flexible, we can design an interface where numbers can be formatted according to their types. The following interface is described in the doc string:

"""
format(::Formatter, x::T) where {T <: Number}

Format a number `x` using the specified formatter.
Returns a string.
"""
function format end

The format function takes a formatter and a numeric value, x, and returns a formatted string. The Formatter type is defined as follows:

abstract type Formatter end
struct IntegerFormatter <: Formatter end
struct FloatFormatter <: Formatter end

Then, the factory methods basically create singleton types for dispatch purposes:

formatter(::Type{T}) where {T <: Integer} = IntegerFormatter()
formatter(::Type{T}) where {T <: AbstractFloat} = FloatFormatter()
formatter(::Type{T}) where T = error("No formatter defined for type $T")

The default implementation may look like the following, utilizing the Printf package:

using Printf
format(nf::IntegerFormatter, x) = @sprintf("%d", x)
format(nf::FloatFormatter, x) = @sprintf("%.2f", x)

Putting everything in a FactoryExample module, we can run the following testing code:

function test()
nf = formatter(Int)
println(format(nf, 1234))
nf = formatter(Float64)
println(format(nf, 1234))
end

The output is as follows:

Should we ever want to change the formatter in the future, we just need to provide a new implementation with format functions defined for the numeric types that we want to support. This is handy when we have a lot of number-formatting code lying around. The switch to a different formatter involves literally two lines of code changes (in this example).

Let's look at the abstract factory pattern next.

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

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