Formatting a price in Swift using an extension vs. a class I have a price as a Double, which I should format it as a String.

Should I use an extension instead of classical class to encapsulate "formater", "serializers", etc? Or is there an even better alternative?

Using Class

class PriceFormatter{
    let value:Double

    init(_ value:Double){
        self.value = value
    }

    func format()-&gt;String{
        let strValue = "\(value)"
        let subStrings = strValue.split(separator: ".")
        let money = subStrings[0]
        var cents = "00"
        if subStrings.count &gt; 1{
            cents = String(subStrings[1])

            if(cents.count == 1){
                cents = "0\(cents)"
            }
        }

        return "$\(money).\(cents)"
    }
}


Using Extension

extension Double {
    var priceFormatted:String{
        let strValue = "\(self)"
        let subStrings = strValue.split(separator: ".")
        let money = subStrings[0]
        var cents = "00"
        if subStrings.count &gt; 1{
            cents = String(subStrings[1])

            if(cents.count == 1){
                cents = "0\(cents)"
            }
        }

        return "$\(money).\(cents)"
    }
}


Implementation

let input:Double = 5.0
let priceFromClass = PriceFormatter(input).format()
let priceFromExtension = input.priceFormatted
Should I use an extension instead of classical class to encapsulate "formatter", "serializers", etc? 


No, it should not be an extension to the numeric type. 

A couple of observations:


This formatter should really work with a variety of types (Double, Float, Decimal, etc.), so burying it inside a particular numeric type’s definition isn’t right. Theoretically you could consider an extension to a protocol, e.g. Numeric, instead, but attaching it to a particular type is certainly not right.
Formatters often have properties of their own. E.g. for a currency formatter, you’d probably have a locale for number formatting, currency symbol, preferred decimal places for that currency, etc., so that speaks to having the formatter as a type, itself, not just some computed property for the numeric type that is being displayed. It also affords the idea of having a single instance of a formatter that you use repeatedly for every underlying object that needs to be displayed.
Note, once you realize that you’re likely to want to configure a formatter once and use it repeatedly, it no longer makes sense to make the value a property of this formatter type. It should be a parameter that we pass to our method for creating a string representation.
By the way, formatters are not just “represent this object as a string”, but also “parse this string into an object” (and sometimes even “is this a valid substring for this type” which you might use to validate input as the user enters it). Once you consider formatters in this context, the notion of burying this in the underlying numeric types starts to run afoul of the “single responsibility principle”. A formatter is, effectively, an object for translating model objects to and from presentations in the UI.
For all of the aforementioned reasons, Foundation has a long tradition of separating data types and their formatters. See Formatter. And there are a litany of existing formatters. You should have a fairly compelling reason before deviating from this well established pattern.
Needless to say, I wouldn’t advise writing your own currency formatter at all when there are existing formatters that do the job very well. As Apple says:


  Before you decide to create a custom formatter, make sure that you cannot configure the public subclasses to satisfy your requirements.


I’d suggest just using NumberFormatter with a numberStyle of one of the currency types (e.g. .currency, .currencyAccounting, etc.).

But I assume this is for illustrative purposes only.
While your code snippet was a “formatter”, you mention serialization.

That’s a different situation where you are often serializing objects with multiple properties of different types. And the serialization is often being handled by an existing serializer objects (e.g., for encoding, JSONEncoder and PropertyListEncoder, etc.). To support serialization for your custom types, you define your type to conform to the Codable protocol.
While presentation and parsing of values in the UI is often handled by separate formatter objects, it’s worth noting that there are a few string representations that we might add to our custom types for debugging purposes. For example, we might conform to CustomStringConvertible so that we can print our values.  Value types (struct) have a decent default string representation, but especially for reference types (class) it can be nice to customize this. 

But don’t be tempted to use description as a backdoor for formatting strings in your UI. As Apple says, 


  Accessing a type’s description property directly or using CustomStringConvertible as a generic constraint is discouraged.


But for diagnostic purposes, this can be useful. Also see CustomDebugStringConvertible.