Строго типизированный идентификатор

Диаграмма классов UML для строго типизированного идентификатора.
Диаграмма классов UML для строго типизированного идентификатора.

Строго типизированный идентификатор — это определяемый пользователем тип данных , который служит идентификатором или ключом, который строго типизирован . Это решение для « запаха кода примитивной одержимости» , упомянутого Мартином Фаулером . Предпочтительно, чтобы тип данных был неизменяемым , если это возможно. Обычно реализации обрабатывают проверку равенства, сериализацию и связывание моделей.

Строго типизированный идентификатор обычно охватывает тип данных, используемый в качестве первичного ключа в базе данных, например строку, целое число или универсальный уникальный идентификатор (UUID).

Веб-фреймворки часто можно настроить для моделирования свойств привязки к моделям представлений, которые являются строго типизированными идентификаторами. Объектно-реляционные преобразователи часто можно настроить с преобразователями значений для сопоставления данных между свойствами в модели с использованием строго типизированных типов данных идентификаторов и столбцов базы данных.

Примеры

Передача строго типизированного идентификатора через слои примера приложения.

Передача строго типизированного идентификатора через слои примера приложения

С#

В C# есть записи, которые обеспечивают неизменность и проверку на равенство. [1] Запись запечатана, чтобы предотвратить наследование . [2] Она переопределяет встроенный ToString()метод. [3]

В этом примере реализации используется статический метод, который можно использовать для инициализации нового экземпляра с помощью случайно сгенерированного глобального уникального идентификатора (GUID).

/// <summary> /// Представляет идентификатор пользователя. /// </summary> /// <param name="Id">Идентификатор пользователя.</param> public sealed record UserId ( Guid Id ) { /// <summary> /// Инициализирует новый экземпляр записи <see cref="UserId" />. /// </summary> /// <returns>Новый объект UserId.</returns> public static UserId New () => new ( Guid . NewGuid ());               публичная переопределенная строка ToString ( ) => Id.ToString ( ); }     

С++

В C++ есть структуры, но нет неизменяемости, поэтому здесь поле id помечено как закрытое с указанным методом value()получения значения.

структура UserId { UserId ( конст строка _id ) { id = _id ; }           строковое значение () const { return id ; }       оператор bool == ( const UserId & rhs ) const { возвращаемое значение () == rhs . значение (); }          частный : строковый идентификатор ; };  ostream & оператор << ( ostream & os , const UserId & id ) { return os << id . value () << std :: endl ; }             

Кристалл

Стандартная библиотека Crystal предоставляет макрос записи для создания записей, которые являются неизменяемыми структурами, и позволяет вам переопределять встроенный to_sметод. [4]

требуется "uuid" # Представляет идентификатор пользователя. record UserId , id : String do def initialize () @id = UUID . v4 . to_s end            def to_s ( io ) io << id конец      def self.empty self.new ( UUID .empty .to_s ) конец конец   

Д

D имеет неизменяемые структуры. [5]

импорт стандартный ; /** Представляет идентификатор пользователя. */ immutable struct UserId { immutable UUID id ;      /** Инициализирует новый экземпляр структуры UserId. */ this ( immutable string id ) { this . id = UUID ( id ); }         public static UserId create ( ) { return UserId ( randomUUID.toString ( ) ); }        строка toString ( ) { вернуть это.id.toString ( ) ; } }     

Дарт

В Dart есть классы с перегрузкой операторов.

импорт 'package:meta/meta.dart' ; /// Представляет идентификатор пользователя. @immutable final class UserId { final String id ;       /// Инициализирует новый экземпляр структуры UserId. const UserId ( this . id );   @override оператор == ( other ) => other is UserId && other . id == id ; @override int get hashCode => id . hashCode ; @override String toString () => id ; }                     

Фа#

F# позволяет создавать переопределенные методы Equals, GetHashCodeи ToString.

открытая система /// <summary> /// Представляет идентификатор пользователя. /// </summary> /// <param name="id">Идентификатор пользователя.</param> type UserId ( id : Guid ) = member x . id = id static member New () = Guid . NewGuid () static member Empty = Guid . Empty override x . Equals ( b ) = match b with | :? UserId as p -> id = p . id | _ - > false override x . GetHashCode () = hash id override x . ToString () = id . ToString ()                                             

Идти

В Go есть структуры, которые обеспечивают проверку равенства. Однако Go не обеспечивает неизменяемости.

// Представляет идентификатор пользователя. type UserId struct { id string }     // Создает новый идентификатор пользователя. func NewUserId ( id string ) UserId { return UserId { id : id } }        func ( xUserId ) String ( ) string { return x.id }        

Круто

В Groovy есть классы записей, которые обеспечивают неизменность и проверку равенства. [6]

/** * Представляет идентификатор пользователя. * * @param id Идентификатор пользователя. */ record UserId ( String id ) { String toString () { id } }        

Хаскелл

Haskell может создавать пользовательские типы данных, используя newtypeключевое слово. [7] Он обеспечивает проверку равенства с использованием Eqстандартного класса и печать с использованием стандартных классов Readи Show.

-- Представляет идентификатор пользователя. newtype UserId = UserId String deriving ( Eq , Read , Show )        

Ява

В Java есть записи, которые обеспечивают проверку равенства. [8] Запись объявляется с использованием finalключевого слова modifier для предотвращения наследования. Она переопределяет встроенный toString()метод.

импорт java.util.UUID ; /** * Представляет идентификатор пользователя. * @param id Идентификатор пользователя. */ public final record UserId ( UUID id ) { /**  * Инициализирует новый экземпляр записи UserId.  * @return Новый объект UserId.  */ public static UserId newId () { return new UserId ( UUID . randomUUID ()); }                public String toString () { return id . toString (); } }      

JavaScript

Этот пример реализации JavaScripttoJSON предоставляет метод, используемый функцией JSON.stringify()[9] для сериализации класса в простую строку вместо составного типа данных . Он вызывает, Object.freeze()чтобы сделать экземпляр неизменяемым. [10] Он переопределяет встроенный toString()метод [11] и valueOf()метод. [12]

класс UserId { # id ;    конструктор ( id ) { if ( id == undefined ) { throw new TypeError ( "Аргумент равен null или не определен." ); } this . # id = id ; Object . freeze ( this ); }                статический пустой = новый этот.прототип.конструктор ( " 00000000-0000-0000-0000-000000000000 " ) ;     static new ( ) { return new this.prototype.constructor ( crypto.randomUUID ( ) ) ; }       equals ( id ) { return id instanceof this.constructor && this . # id === id.valueOf ( ) ; }           toJSON () { вернуть это . # id ; }     toString () { вернуть это . # id ; }     valueOf () { вернуть это . # id ; } }    

Джулия

У Julia есть неизменяемые составные типы данных. [13]

использование UUID "Представляет идентификатор пользователя." struct  UserId id :: UUID end База.строка ( userId :: UserId ) = userId.id  

Котлин

В Kotlin есть «встроенные классы». [14]

/** * Представляет идентификатор пользователя. * * @property id Идентификатор пользователя. * @constructor Создает идентификатор пользователя. */ @JvmInline public value class UserId ( public val id : String ) { override fun toString () = id }            

Ним

Ним имеет «отдельные типы». [15] [16]

## Представляет идентификатор пользователя. type UserId * = отдельная строка    

PHP

Этот пример реализации PHP__toString() реализует магический метод. [17] Кроме того, он реализует JsonSerializableинтерфейс, который используется встроенной json_encodeфункцией для сериализации класса в простую строку вместо составного типа данных . [18] Класс объявляется с использованием finalключевого слова modifier для предотвращения наследования. [19] В PHP есть черты как способ повторного использования кода. [20]

/** * Представляет идентификатор пользователя. */ final  class  UserId  implements  JsonSerializable {  use  StronglyTypedIdentifier ; }/** * Предоставляет методы для использования со строго типизированными идентификаторами. */ trait  StronglyTypedIdentifier {  /**  * Инициализирует новый экземпляр объекта UserId.  * @param string $id Идентификатор пользователя.  */  public  function  __construct ( public  readonly  string  $id )  {} /**  * Создает новый идентификатор пользователя.  */  public  static  function  new () :  self  {  return  new  self ( bin2hex ( random_bytes ( 16 )));  } публичная  функция  jsonSerialize () :  string  {  return  $this -> id ;  } публичная  функция  __toString () :  string  {  return  $this -> id ;  } }

Питон

В Python есть классы данных, которые обеспечивают проверку равенства и могут быть сделаны неизменяемыми с помощью frozenпараметра. [21] Он переопределяет __str__метод dunder. [22]

В этом примере реализации реализован статический метод, который можно использовать для инициализации нового экземпляра с помощью случайно сгенерированного универсального уникального идентификатора (UUID).

из  dataclasses  импорт  dataclass импорт  uuid@dataclass ( frozen = True ) class  UserId : """Представляет идентификатор пользователя."""  id :  uuid . UUID @staticmethod  def  new ()  ->  Self : """Создать новый идентификатор пользователя.""" return __class__ ( uuid . uuid4 ())    def  __str__ ( self ):  возвращает  str ( self . id )

У Python также есть NewTypeязык программирования, который можно использовать для создания новых типов данных. [23]

от  ввода  import  NewTypeUserId  =  NewType ( 'UserId' ,  int )

Рубин

В Ruby есть классы данных, которые обеспечивают проверку равенства и являются неизменяемыми. [24] Он переопределяет встроенный to_sметод.

В этом примере реализации реализован статический метод, который можно использовать для инициализации нового экземпляра с помощью случайно сгенерированного универсального уникального идентификатора (UUID).

требуется «securerandom» # Представляет идентификатор пользователя. UserId = Data . define ( :id ) do # Создать новый идентификатор пользователя. def self . create self . new ( SecureRandom . uuid ) end         def self.empty self.new ( ' 00000000-0000-0000-0000-000000000000 ' ) end    def to_s id конец конец   

Ржавчина

В Rust это можно сделать с помощью структуры кортежа, содержащей одно значение. [25] Этот пример реализации реализует черты Debug[26] и PartialEq[27] . Черта обеспечивает проверку равенства.PartialEq

// Представляет идентификатор пользователя. #[derive(Debug, PartialEq)] pub struct UserId ( String );  

Скала

В Scala есть классы case, которые обеспечивают неизменность и проверку равенства. [28] Класс case запечатан, чтобы предотвратить наследование.

импорт java.util.UUID /** Представляет идентификатор пользователя.  *  * @constructor  * Создает новый идентификатор пользователя.  * @param id  * Идентификатор пользователя.  */ sealed case class UserId ( id : UUID )    object UserId : /** Инициализирует новый экземпляр класса UserId. */ def create (): UserId = UserId ( UUID . randomUUID ())       

Быстрый

В Swift есть CustomStringConvertibleпротокол, который можно использовать для предоставления собственного представления, используемого при преобразовании экземпляра в строку, [29] и Equatableпротокол, который обеспечивает проверку равенства. [30]

импортный  фонд/// Представляет идентификатор пользователя. struct  UserId :  CustomStringConvertible ,  Equatable  {  private  let  id :  UUID init ( _id  : UUID ) { self.id = id }       var  description :  String  {  return  id . uuidString . нижний регистр  } /// Создает новый идентификатор пользователя.  static  func  new ()  ->  Self  {  return  Self ( UUID ())  } }

Зиг

Zig имеет структуры [31] с константами, но по своей конструкции не имеет перегрузки операторов [32] и переопределения методов.

/// Представляет идентификатор пользователя. const UserId = struct { value : i32 ,       /// Инициализирует новый экземпляр структуры UserId. pub fn init ( value : i32 ) UserId { return UserId { . value = value }; } };             

Смотрите также

Ссылки

  1. ^ "Records - C# reference". learn.microsoft.com . Получено 23 января 2023 г. .
  2. ^ "sealed modifier - C# Reference". learn.microsoft.com . Получено 23 января 2023 г. .
  3. ^ "Метод Object.ToString (Система)". learn.microsoft.com . Получено 14 июня 2023 г. .
  4. ^ "Structs - Crystal". crystal-lang.org . Получено 21 февраля 2024 г. .
  5. ^ "Structs, Unions - D Programming Language". dlang.org . Получено 30 мая 2023 г. .
  6. ^ "Язык программирования Apache Groovy — объектная ориентация". groovy-lang.org . Получено 24 декабря 2023 г. .
  7. ^ "Newtype - HaskellWiki". wiki.haskell.org . Получено 18 июня 2023 г. .
  8. ^ "Record Classes". Oracle Help Center . Получено 24 января 2023 г.
  9. ^ "JSON.stringify() - JavaScript | MDN". developer.mozilla.org . Получено 23 января 2023 г. .
  10. ^ "Object.freeze() - JavaScript | MDN". developer.mozilla.org . Получено 23 января 2023 г. .
  11. ^ "Object.prototype.toString() - JavaScript | MDN". developer.mozilla.org . Получено 23 января 2023 г. .
  12. ^ "Object.prototype.valueOf() - JavaScript | MDN". developer.mozilla.org . Получено 23 января 2023 г. .
  13. ^ "Типы · Язык Джулии". docs.julialang.org . Получено 30 мая 2023 г. .
  14. ^ "Встроенные классы | Kotlin". Справка по Kotlin . Получено 23 января 2023 г.
  15. ^ "Руководство по Nim". nim-lang.org . Получено 4 августа 2023 г. .
  16. ^ "Nim by Example - Distinct Types". nim-by-example.github.io . Получено 4 августа 2023 г. .
  17. ^ "PHP: Magic Methods - Manual". www.php.net . Получено 23 января 2023 г. .
  18. ^ "PHP: JsonSerializable::jsonSerialize - Руководство". www.php.net . Получено 23 января 2023 г. .
  19. ^ "PHP: Final Keyword - Manual". www.php.net . Получено 23 января 2023 г. .
  20. ^ "PHP: Traits - Manual". www.php.net . Получено 2 мая 2023 г. .
  21. ^ "dataclasses — Data Classes". Документация Python . Python Software Foundation . Получено 23 января 2023 г.
  22. ^ "3. Модель данных". Документация Python . Python Software Foundation . Получено 12 июня 2023 г.
  23. ^ "typing — Support for type hints". Документация Python . Python Software Foundation . Получено 17 июня 2023 г.
  24. ^ "class Data - Документация по Ruby 3.3". docs.ruby-lang.org . Получено 6 февраля 2023 г. .
  25. ^ "New Type Idiom - Rust By Example". doc.rust-lang.org . Получено 18 июня 2023 г. .
  26. ^ "Отладка в std::fmt - Rust". doc.rust-lang.org . Получено 23 января 2023 г. .
  27. ^ "PartialEq in std::cmp - Rust". doc.rust-lang.org . Получено 23 января 2023 г. .
  28. ^ "Case Classes". Документация Scala . Получено 15 мая 2023 г.
  29. ^ "CustomStringConvertible". Документация разработчика Apple . Получено 5 мая 2023 г.
  30. ^ "Документация". docs.swift.org . Получено 4 мая 2023 г. .
  31. ^ "Structs | zig.guide". zig.guide . 20 апреля 2024 г. Получено 15 октября 2024 г.
  32. ^ "Документация - Язык программирования Zig" . Получено 15 октября 2024 г. .
  • https://wiki.c2.com/?PrimitiveObsession
Взято с "https://en.wikipedia.org/w/index.php?title=Идентификатор_строго_типа&oldid=1254328802"