Movatterモバイル変換


[0]ホーム

URL:


Jump to content
WikipediaThe Free Encyclopedia
Search

Strongly typed identifier

From Wikipedia, the free encyclopedia
A UML class diagram for a strongly typed identifier.
A UML class diagram for a strongly typed identifier.

Astrongly typed identifier is user-defineddata type which serves as an identifier or key that isstrongly typed. This is a solution to the "primitive obsession"code smell as mentioned byMartin Fowler. The data type should preferably beimmutable if possible. It is common for implementations to handle equality testing,serialization and model binding.

The strongly typed identifier commonly wraps the data type used as theprimary key in the database, such as a string, an integer oruniversally unique identifier (UUID).

Web frameworks can often be configured to model bind properties on view models that are strongly typed identifiers.Object–relational mappers can often be configured with value converters to map data between the properties on a model using strongly typed identifier data types and database columns.

Examples

[edit]

Passing a strongly typed identifier throughout the layers of an example application.

Passing a strongly typed identifier throughout the layers of an example application

C#

[edit]

C# have records which provide immutability and equality testing.[1] The record is sealed to preventinheritance.[2] It overrides the built-inToString() method.[3]

This example implementation includes a static method which can be used to initialize a new instance with a randomly generatedglobally unique identifier (GUID).

/// <summary>/// Represents a user identifier./// </summary>/// <param name="Id">The user identifier.</param>publicsealedrecordUserId(GuidId){/// <summary>/// Initializes a new instance of the <see cref="UserId" /> record./// </summary>/// <returns>A new UserId object.</returns>publicstaticUserIdNew()=>new(Guid.NewGuid());publicoverridestringToString()=>Id.ToString();}

C++

[edit]

C++ has structs but not immutability so here the id field is marked as private with a method namedgetId() to get the value.

importstd;usingstd::string;classUserId{private:conststringid;public:explicitUserId(conststring&id):id{id}{}[[nodiscard]]stringgetId()constnoexcept{returnid;}[[nodiscard]]booloperator==(constUserId&rhs)constnoexcept{returnid==rhs.getId();}};

Crystal

[edit]

Crystal's standard library provides the record macro for creating records which are immutable structs and lets you create override the built-into_s method.[4]

require"uuid"# Represents a user identifier.recordUserId,id:Stringdodefinitialize()@id=UUID.v4.to_senddefto_s(io)io<<idenddefself.emptyself.new(UUID.empty.to_s)endend

D

[edit]

D have immutable structs.[5]

importstd;/** Represents a user identifier. */immutablestructUserId{immutableUUIDid;/** Initializes a new instance of the UserId struct. */this(immutablestringid){this.id=UUID(id);}publicstaticUserIdcreate(){returnUserId(randomUUID.toString());}stringtoString(){returnthis.id.toString();}}

Dart

[edit]

Dart have classes with operator overloading.

import'package:meta/meta.dart';/// Represents a user identifier.@immutablefinalclassUserId{finalStringid;/// Initializes a new instance of the UserId struct.constUserId(this.id);@overrideoperator==(other)=>otherisUserId&&other.id==id;@overrideintgethashCode=>id.hashCode;@overrideStringtoString()=>id;}

F#

[edit]

F# lets you create override theEquals,GetHashCode andToString methods.

openSystem/// <summary>/// Represents a user identifier./// </summary>/// <param name="id">The user identifier.</param>typeUserId(id:Guid)=memberx.id=idstaticmemberNew()=Guid.NewGuid()staticmemberEmpty=Guid.Emptyoverridex.Equals(b)=matchbwith|:?UserIdasp->id=p.id|_->falseoverridex.GetHashCode()=hashidoverridex.ToString()=id.ToString()

Go

[edit]

Go have structs which provide equality testing. Go however does not provide immutability.

// Represents a user identifier.typeUserIdstruct{idstring}// Creates a new user identifier.funcNewUserId(idstring)UserId{returnUserId{id:id}}func(xUserId)String()string{returnx.id}

Groovy

[edit]

Groovy have record classes which provide immutability and equality testing.[6]

/** * Represents a user identifier. * * @param id The user identifier. */recordUserId(Stringid){StringtoString(){id}}

Haskell

[edit]

Haskell can create user-defined custom data types using thenewtype keyword.[7] It provides equality testing using theEq standard class and printing using theRead andShow standard classes.

-- Represents a user identifier.newtypeUserId=UserIdStringderiving(Eq,Read,Show)

Java

[edit]

Java have records which provide equality testing.[8]The record is declared using thefinal modifier keyword to prevent inheritance. It overrides the built-intoString() method.

importjava.util.UUID;/** * Represents a user identifier. * @param id The user identifier. */publicfinalrecordUserId(UUIDid){/**     * Initializes a new instance of the UserId record.     * @return A new UserId object.     */publicstaticUserIdnewId(){returnnewUserId(UUID.randomUUID());}publicStringtoString(){returnid.toString();}}

JavaScript

[edit]

ThisJavaScript example implementation provides thetoJSON method used by theJSON.stringify()[9] function to serialize the class into a simple string instead of acomposite data type.It callsObject.freeze() to make the instance immutable.[10]It overrides the built-intoString() method[11] and thevalueOf() method.[12]

classUserId{#id;constructor(id){if(id==undefined){thrownewTypeError("Argument is null or undefined.");}this.#id=id;Object.freeze(this);}staticempty=newthis.prototype.constructor("00000000-0000-0000-0000-000000000000");staticnew(){returnnewthis.prototype.constructor(crypto.randomUUID());}equals(id){returnidinstanceofthis.constructor&&this.#id===id.valueOf();}toJSON(){returnthis.#id;}toString(){returnthis.#id;}valueOf(){returnthis.#id;}}

Julia

[edit]

Julia have immutable composite data types.[13]

usingUUIDs"Represents a user identifier."structUserIdid::UUIDendBase.string(userId::UserId)=userId.id

Kotlin

[edit]

Kotlin have "inline classes".[14]

/** * Represents a user identifier. * * @property id The user identifier. * @constructor Creates a user identifier. */@JvmInlinepublicvalueclassUserId(publicvalid:String){overridefuntoString()=id}

Nim

[edit]

Nim have "distinct types".[15][16]

## Represents a user identifier.typeUserId*=distinctstring

PHP

[edit]

ThisPHP example implementation implements the__toString() magic method.[17]Furthermore, it implements theJsonSerializable interface which is used by the built-injson_encode function to serialize the class into a simple string instead of acomposite data type.[18]The class is declared using thefinal modifier keyword to prevent inheritance.[19]PHP has traits as a way to re-use code.[20]

/** * Represents a user identifier. */finalclassUserIdimplementsJsonSerializable{useStronglyTypedIdentifier;}/** * Provides methods for use with strongly typed identifiers. */traitStronglyTypedIdentifier{/**     * Initializes a new instance of the UserId object.     * @param string $id The user identifier.     */publicfunction__construct(publicreadonlystring$id){}/**     * Creates a new user identifier.     */publicstaticfunctionnew():self{returnnewself(bin2hex(random_bytes(16)));}publicfunctionjsonSerialize():string{return$this->id;}publicfunction__toString():string{return$this->id;}}

Python

[edit]

Python has data classes which provides equality testing and can be made immutable using thefrozen parameter.[21] It overrides the__str__ dunder method.[22]

This example implementation includes a static method which can be used to initialize a new instance with a randomly generateduniversally unique identifier (UUID).

importuuidfromdataclassesimportdataclassfromuuidimportUUID@dataclass(frozen=True)classUserId:"""Represents a user identifier."""id:UUID@staticmethoddefnew()->Self:"""Create a new user identifier."""return__class__(uuid.uuid4())def__str__(self)->str:returnstr(self.id)

Python also hasNewType which can be used to create new data types.[23]

fromtypingimportNewTypeUserId:NewType=NewType('UserId',int)

Raku

[edit]

Raku have classes which provides equality testing and are immutable. It overrides the built-inStr method.

This example overrides the default gist method.[24] It uses roles which are mixed in into classes to be re-usable.[25]

roleStronglyTypedIdentifier {hasStr$.idisrequired;multimethodnew(Str$id) {self.bless(:$id);    }multimethodgist(StronglyTypedIdentifier:U:) {self.^name }multimethodgist(StronglyTypedIdentifier:D:) {self.id }methodStr() {"$!id" }methodempty() {self.new("00000000-0000-0000-0000-000000000000")    }}classUserIddoesStronglyTypedIdentifier {}

Ruby

[edit]

Ruby have data classes which provides equality testing and are immutable.[26] It overrides the built-into_s method.

This example implementation includes a static method which can be used to initialize a new instance with a randomly generateduniversally unique identifier (UUID).

require'securerandom'# Represents a user identifier.UserId=Data.define(:id)do# Create a new user identifier.defself.createself.new(SecureRandom.uuid)enddefself.emptyself.new('00000000-0000-0000-0000-000000000000')enddefto_sidendend

Rust

[edit]

InRust this can be done using atuple struct containing a single value.[27] This example implementation implements theDebug[28] and thePartialEq[29]traits. ThePartialEq trait provides equality testing.

// Represents a user identifier.#[derive(Debug, PartialEq)]pubstructUserId(String);

Scala

[edit]

Scala have case classes which provide immutability and equality testing.[30] The case class is sealed to prevent inheritance.

importjava.util.UUID/** Represents a user identifier.  *  * @constructor  *   Create a new user identifier.  * @param id  *   The user identifier.  */sealedcaseclassUserId(id:UUID)objectUserId:/** Initializes a new instance of the UserId class. */defcreate():UserId=UserId(UUID.randomUUID())

Swift

[edit]

Swift have theCustomStringConvertible protocol which can be used to provide its own representation to be used when converting an instance to a string,[31] and theEquatable protocol which provides equality testing.[32]

importFoundation/// Represents a user identifier.structUserId:CustomStringConvertible,Equatable{privateletid:UUIDinit(_id:UUID){self.id=id}vardescription:String{returnid.uuidString.lowercased}/// Creates a new user identifier.staticfuncnew()->Self{returnSelf(UUID())}}

Zig

[edit]

Zig have structs[33] with constants but by design does not have operator overloading[34] and method overriding.

/// Represents a user identifier.constUserId=struct{value:i32,/// Initializes a new instance of the UserId struct.pubfninit(value:i32)UserId{returnUserId{.value=value};}};

See also

[edit]

References

[edit]
  1. ^"Records - C# reference".learn.microsoft.com. Retrieved23 January 2023.
  2. ^"sealed modifier - C# Reference".learn.microsoft.com. Retrieved23 January 2023.
  3. ^"Object.ToString Method (System)".learn.microsoft.com. Retrieved14 June 2023.
  4. ^"Structs - Crystal".crystal-lang.org. Retrieved21 February 2024.
  5. ^"Structs, Unions - D Programming Language".dlang.org. Retrieved30 May 2023.
  6. ^"The Apache Groovy programming language - Object orientation".groovy-lang.org. Retrieved24 December 2023.
  7. ^"Newtype - HaskellWiki".wiki.haskell.org. Retrieved18 June 2023.
  8. ^"Record Classes".Oracle Help Center. Retrieved24 January 2023.
  9. ^"JSON.stringify() - JavaScript | MDN".developer.mozilla.org. Retrieved23 January 2023.
  10. ^"Object.freeze() - JavaScript | MDN".developer.mozilla.org. Retrieved23 January 2023.
  11. ^"Object.prototype.toString() - JavaScript | MDN".developer.mozilla.org. Retrieved23 January 2023.
  12. ^"Object.prototype.valueOf() - JavaScript | MDN".developer.mozilla.org. Retrieved23 January 2023.
  13. ^"Types · The Julia Language".docs.julialang.org. Retrieved30 May 2023.
  14. ^"Inline classes | Kotlin".Kotlin Help. Retrieved23 January 2023.
  15. ^"Nim Manual".nim-lang.org. Retrieved4 August 2023.
  16. ^"Nim by Example - Distinct Types".nim-by-example.github.io. Retrieved4 August 2023.
  17. ^"PHP: Magic Methods - Manual".www.php.net. Retrieved23 January 2023.
  18. ^"PHP: JsonSerializable::jsonSerialize - Manual".www.php.net. Retrieved23 January 2023.
  19. ^"PHP: Final Keyword - Manual".www.php.net. Retrieved23 January 2023.
  20. ^"PHP: Traits - Manual".www.php.net. Retrieved2 May 2023.
  21. ^"dataclasses — Data Classes".Python documentation.Python Software Foundation. Retrieved23 January 2023.
  22. ^"3. Data model".Python documentation.Python Software Foundation. Retrieved12 June 2023.
  23. ^"typing — Support for type hints".Python documentation.Python Software Foundation. Retrieved17 June 2023.
  24. ^"Classes and objects | Raku Documentation".docs.raku.org. Retrieved30 December 2025.
  25. ^"Object orientation | Raku Documentation".docs.raku.org. Retrieved30 December 2025.
  26. ^"class Data - Documentation for Ruby 3.3".docs.ruby-lang.org. Retrieved6 February 2023.
  27. ^"New Type Idiom - Rust By Example".doc.rust-lang.org. Retrieved18 June 2023.
  28. ^"Debug in std::fmt - Rust".doc.rust-lang.org. Retrieved23 January 2023.
  29. ^"PartialEq in std::cmp - Rust".doc.rust-lang.org. Retrieved23 January 2023.
  30. ^"Case Classes".Scala Documentation. Retrieved15 May 2023.
  31. ^"CustomStringConvertible".Apple Developer Documentation. Retrieved5 May 2023.
  32. ^"Documentation".docs.swift.org. Retrieved4 May 2023.
  33. ^"Structs | zig.guide".zig.guide. 20 April 2024. Retrieved15 October 2024.
  34. ^"Documentation - The Zig Programming Language". Retrieved15 October 2024.

External links

[edit]
Uninterpreted
Numeric
Reference
Text
Composite
Other
Related
topics
Gang of Four
patterns
Creational
Structural
Behavioral
Concurrency
patterns
Architectural
patterns
Other
patterns
Books
People
Communities
See also
Retrieved from "https://en.wikipedia.org/w/index.php?title=Strongly_typed_identifier&oldid=1330287283"
Categories:
Hidden categories:

[8]ページ先頭

©2009-2026 Movatter.jp