Якщо ви можете надати класу достатньо корисної функціональності, щоб виправдати додану складність того, що це не рядок, тоді зробіть це. Підозрюю, що для таких ідентифікаторів, як ISBN та ISIN, це не так.
Щоб клас ідентифікатора був корисним, я очікую, що він виглядатиме приблизно так:
class ISIN {
fromCUSIP()
fromRawISINString()
toString(ISIN::FormatType)
getExchange()
getCountryCode()
getLastFourDigits()
getWhateverCode()
...
}
Якщо натомість це виглядає більше так:
class ISIN {
getString()
setString()
}
Тоді я б повністю скинув клас, використовую регулярні рядки скрізь і переконуюсь, що я послідовно використовую "isin" у всіх відповідних назвах змінних.
Зауважте, що в деяких мовах додавання нового типу майже не має «додаткової складності» у типових програмах, і в цьому випадку вам буде запропоновано створити новий тип, навіть якщо він не мав би функціоналу взагалі. Але це не стосується більшості традиційних мов OOP, таких як C ++.