Si puede proporcionar a la clase suficiente funcionalidad útil para justificar la complejidad añadida de no ser una cadena, entonces hágalo. Para identificadores como ISBN e ISIN, sospecho que este no es el caso.
Para que una clase de identificador sea útil, esperaría que se vea así:
class ISIN {
fromCUSIP()
fromRawISINString()
toString(ISIN::FormatType)
getExchange()
getCountryCode()
getLastFourDigits()
getWhateverCode()
...
}
Si en cambio se parece más a esto:
class ISIN {
getString()
setString()
}
Luego abandonaría la clase por completo, usaría cadenas regulares en todas partes y me aseguraría de usar consistentemente "isin" en todos los nombres de variables relevantes.
Tenga en cuenta que, en algunos idiomas, agregar un nuevo tipo casi no tiene "complejidad añadida" en los programas típicos, en cuyo caso se le recomendaría crear el nuevo tipo incluso si no tuviera ninguna funcionalidad. Pero este no es el caso para la mayoría de los lenguajes OOP tradicionales como C ++.