Articulo de referencia

Identificador fuertemente tipado

Un diagrama de clases UML para un identificador fuertemente tipado. Un identificador fuertemente tipado es un tipo de datos definido por el usuario que sirve como un identificad...

Un diagrama de clases UML para un identificador fuertemente tipado.
Un diagrama de clases UML para un identificador fuertemente tipado.

Un identificador fuertemente tipado es un tipo de datos definido por el usuario que sirve como un identificador o clave fuertemente tipado . Esta es una solución al problema del código "obsesión primitiva" mencionado por Martin Fowler . El tipo de datos debería ser preferiblemente inmutable si es posible. Es común que las implementaciones manejen pruebas de igualdad, serialización y vinculación de modelos.

El identificador fuertemente tipado comúnmente envuelve el tipo de datos utilizado como clave principal en la base de datos, como una cadena, un entero o un identificador único universal (UUID).

Los marcos web se pueden configurar a menudo para modelar propiedades de enlace en modelos de vista que son identificadores fuertemente tipados. Los mapeadores relacionales de objetos se pueden configurar a menudo con convertidores de valores para mapear datos entre las propiedades de un modelo utilizando tipos de datos de identificadores fuertemente tipados y columnas de base de datos.

Ejemplos

Pasar un identificador fuertemente tipado a lo largo de las capas de una aplicación de ejemplo.

Pasar un identificador fuertemente tipado a través de las capas de una aplicación de ejemplo

DO#

C# tiene registros que proporcionan inmutabilidad y pruebas de igualdad. [1] El registro está sellado para evitar la herencia . [2] Anula el método integrado ToString(). [3]

Esta implementación de ejemplo incluye un método estático que se puede utilizar para inicializar una nueva instancia con un identificador único global (GUID) generado aleatoriamente.

/// <summary> 
/// Representa un identificador de usuario. 
/// </summary> 
/// <param name="Id">El identificador de usuario.</param> 
public sealed record UserId ( Guid Id ) { /// <summary> /// Inicializa una nueva instancia del registro <see cref="UserId" />. /// </summary> /// <returns>Un nuevo objeto UserId.</returns> public static UserId New () => new ( Guid . NewGuid ());    

    
    
    
    
         

    cadena pública de anulación ToString ( ) = > Id.ToString (); }     

C++

C++ tiene estructuras pero no inmutabilidad, por lo que aquí el campo id está marcado como privado con un método nombrado value()para obtener el valor.

estructura UserId { UserId ( cadena constante _id ) { id = _id ; }  
      
    
          
    

    valor de cadena () const { return id ; }  
    
         
    

    operador bool == ( const UserId & rhs ) const { valor de retorno () == rhs . valor (); }    
    
           
    

privado : 
cadena id ; };     


ostream & operador << ( ostream & os , const UserId & id ) { return os << id . valor () << std :: endl ; }       

         

Cristal

La biblioteca estándar de Crystal proporciona la macro de registro para crear registros que son estructuras inmutables y le permite crear o anular el método incorporado to_s. [4]

requiere "uuid" 

# Representa un identificador de usuario. 
record UserId , id : String do def initialize () @id = UUID . v4 . to_s end     
   
      
  

  def to_s ( io ) io << id fin 
      
  

  def self . empty self . new ( UUID . empty . to_s ) fin fin 
    
  

D

D tiene estructuras inmutables. [5]

importar std ; 

/** Representa un identificador de usuario. */ 
immutable struct UserId { immutable UUID id ;  

      

    /** Inicializa una nueva instancia de la estructura UserId. */ 
this ( cadena inmutable id ) { this . id = UUID ( id ); }      
    
          
    

    público estático UserId crear () { devolver UserId ( randomUUID.toString ( ) ); }   
    
         
    

    cadena toString () { devuelve este .id .toString ( ) ; } } 
    
         
    

Dardo

Dart tiene clases con sobrecarga de operadores.

importar 'paquete:meta/meta.dart' ; 

/// Representa un identificador de usuario. 
@immutable 
final class UserId { final String id ;   
    

  
/// Inicializa una nueva instancia de la estructura UserId. const UserId ( this.id ) ;   

  @override 
operador == ( otro ) => otro es UserId && otro . id == id ; @override int obtener hashCode => id . hashCode ; @override String toString () => id ; }           
  
      
  
     

F#

F# le permite crear y anular los métodos Equals, GetHashCodey ToString.

Sistema abierto 


/// <summary> /// Representa un identificador de usuario. 
/// </summary> /// < 
param name="id">El identificador de 
usuario . </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 ( )   
       
        
        
      
        
              
         
        
       

Ir

Go tiene estructuras que permiten realizar pruebas de igualdad, pero no ofrece inmutabilidad.

// Representa un identificador de usuario. 
tipo UserId struct { id string }     

// Crea un nuevo identificador de usuario. 
func NewUserId ( id string ) UserId { return UserId { id : id } }        

func ( x UserId ) String () cadena { devolver x . id }        

Genial

Groovy tiene clases de registros que proporcionan inmutabilidad y pruebas de igualdad. [6]

/** 
* Representa un identificador de usuario. 
* 
* @param id El identificador de usuario. 
*/ 
record UserId ( String id ) { String toString () { id } }   
        

Haskell

Haskell puede crear tipos de datos personalizados definidos por el usuario utilizando la newtypepalabra clave. [7] Proporciona pruebas de igualdad utilizando la Eqclase estándar e impresión utilizando las clases estándar Ready Show.

-- Representa un identificador de usuario. 
newtype UserId = UserId String deriving ( Eq , Read , Show )        

Java

Java tiene registros que permiten realizar pruebas de igualdad. [8] El registro se declara utilizando la palabra clave modificadora para evitar la herencia. Anula el método finalincorporado .toString()

importar java.util.UUID ; 

/** 
* Representa un identificador de usuario. 
* @param id El identificador de usuario. 
*/ 
public final record UserId ( UUID id ) { /**      * Inicializa una nueva instancia del registro UserId.      * @return Un nuevo objeto UserId.      */ public static UserId newId () { return new UserId ( UUID . randomUUID ()); }     
    



        
          
    

    público String toString () { devolver id . toString (); } }   
         
    

JavaScript

Esta implementación de ejemplo de JavaScript proporciona el toJSONmétodo utilizado por la función JSON.stringify()[9] para serializar la clase en una cadena simple en lugar de un tipo de datos compuesto . Llama Object.freeze()para hacer que la instancia sea inmutable. [10]toString() Anula el método incorporado [11] y el valueOf()método. [12]

clase UserId { # id ;  
  

  constructor ( id ) { if ( id == undefined ) { throw new TypeError ( "El argumento es nulo o indefinido." ); } this . # id = id ; Object . freeze ( this ); } 
        
        
    
      
    
  

  static empty = new this . prototipo . constructor ( "00000000-0000-0000-0000-000000000000" );    

  static new ( ) { devolver nuevo this.prototype.constructor ( crypto.randomUUID ( ) ) ; }  
      
  

  es igual a ( id ) { devolver id instanciade este . constructor && este . # id === id . valorDe (); } 
           
  

  toJSON () { devuelve este . # id ; } 
  	 
  

  toString () { devuelve este . # id ; } 
     
  

  valueOf () { devuelve este . # id ; } } 
  	 
  

Julia

Julia tiene tipos de datos compuestos inmutables. [13]

utilizando UUID 

"Representa un identificador de usuario". 
struct  UserId 
id :: UUID end    


Base . cadena ( userId :: UserId ) = userId . id  

Kotlin

Kotlin tiene "clases en línea". [14]

/** 
* Representa un identificador de usuario. 
* 
* @property id El identificador de usuario. 
* @constructor Crea un identificador de usuario. 
*/ 
@JvmInline 
public value class UserId ( public val id : String ) { override fun toString () = id }       
        

Nim

Los nim tienen "tipos distintos". [15] [16]

## Representa un identificador de usuario. 
tipo UserId * = cadena distinta    

PHP

Esta implementación de ejemplo de PHP implementa el __toString()método mágico. [17] Además, implementa la JsonSerializableinterfaz que utiliza la función incorporada json_encodepara serializar la clase en una cadena simple en lugar de un tipo de datos compuesto . [18] La clase se declara utilizando la finalpalabra clave modificadora para evitar la herencia. [19] PHP tiene rasgos como una forma de reutilizar el código. [20]

/** 
* Representa un identificador de usuario. 
*/ 
final  class  UserId  implements  JsonSerializable 
{ 
    use  StronglyTypedIdentifier ; 
}

/** 
* Proporciona métodos para usar con identificadores fuertemente tipados. 
*/ 
trace  StronglyTypedIdentifier 
{ 
    /** 
     * Inicializa una nueva instancia del objeto UserId. 
     * @param string $id El identificador del usuario. 
     */ 
    public  function  __construct ( public  readonly  string  $id )  {}

    /** 
     * Crea un nuevo identificador de usuario. 
     */ 
    public  static  function  new () :  self 
    { 
        return  new  self ( bin2hex ( random_bytes ( 16 ))); 
    }

     función  pública jsonSerialize () :  cadena 
    { 
        return  $this -> id ; 
    }

     función  pública __toString () :  cadena 
    { 
        return  $this -> id ; 
    } 
}

Pitón

Python tiene clases de datos que proporcionan pruebas de igualdad y pueden hacerse inmutables usando el frozenparámetro. [21] Anula el __str__método dunder. [22]

Esta implementación de ejemplo incluye un método estático que se puede utilizar para inicializar una nueva instancia con un identificador único universal (UUID) generado aleatoriamente.

desde  dataclasses  importar  dataclass 
importar  uuid

@dataclass ( frozen = True ) 
clase  UserId : 
"""Representa un identificador de usuario."""    

    Identificación :  UUID . UUID

    @staticmethod 
    def  new ()  ->  Self : 
"""Crear un nuevo identificador de usuario.""" return __class__ ( uuid . uuid4 ())        
         

    def  __str __ ( self ) 
        : devuelve  str ( self.id )

Python también tiene NewTypela función que se puede utilizar para crear nuevos tipos de datos. [23]

desde  la escritura  importar  NewType

UserId  =  NewType ( 'UserId' ,  int )

Rubí

Ruby tiene clases de datos que proporcionan pruebas de igualdad y son inmutables. [24] Anula el método incorporado to_s.

Esta implementación de ejemplo incluye un método estático que se puede utilizar para inicializar una nueva instancia con un identificador único universal (UUID) generado aleatoriamente.

requiere 'securerandom' 

# Representa un identificador de usuario. 
UserId = Data . define ( :id ) do # Crea un nuevo identificador de usuario. def self . create self . new ( SecureRandom . uuid ) end   
  
   
    
  

  def self . vacío self . nuevo ( '00000000-0000-0000-0000-000000000000' ) fin 
    
  

  def to_s id fin fin 
    
  

Óxido

En Rust, esto se puede hacer usando una estructura de tupla que contiene un único valor. [25] Esta implementación de ejemplo implementa los rasgos Debug[26] y PartialEq[27] . El rasgo proporciona pruebas de igualdad. PartialEq

// Representa un identificador de usuario. 
#[derive(Debug, PartialEq)] 
pub struct UserId ( String );  

Escala

Scala tiene clases de caso que proporcionan inmutabilidad y pruebas de igualdad. [28] La clase de caso está sellada para evitar la herencia.

importar java .util .UUID 

/** Representa un identificador de usuario. 
  * 
  * @constructor 
  * Crea un nuevo identificador de usuario. 
  * @param id 
  * El identificador de usuario. 
  */ 
sealed case class UserId ( id : UUID )    

object UserId : /** Inicializa una nueva instancia de la clase UserId. */ def create (): UserId = UserId ( UUID . randomUUID ()) 
  
      

Rápido

Swift tiene el CustomStringConvertibleprotocolo que se puede utilizar para proporcionar su propia representación para ser utilizada al convertir una instancia en una cadena, [29] y el Equatableprotocolo que proporciona pruebas de igualdad. [30]

 Fundación de importación

/// Representa un identificador de usuario. 
struct  UserId :  CustomStringConvertible ,  Equatable  { 
    private  let  id :  UUID

    init ( _id  : UUID ) { self.id = id }  
          
    

    var  description :  String  { 
        return  id . uuidString . lowercased 
    }

    /// Crea un nuevo identificador de usuario. 
    static  func  new ()  ->  Self  { 
        return  Self ( UUID ()) 
    } 
}

Zig

Zig tiene estructuras [31] con constantes pero por diseño no tiene sobrecarga de operadores [32] ni anulación de métodos.

/// Representa un identificador de usuario. 
const UserId = struct { value : i32 ,    
     

    /// Inicializa una nueva instancia de la estructura UserId. 
pub fn init ( value : i32 ) UserId { return UserId { . value = value }; } };         
             
    

Véase también

Referencias

  1. ^ "Registros - Referencia de C#". learn.microsoft.com . Consultado el 23 de enero de 2023 .
  2. ^ "Modificador sellado - Referencia de C#". learn.microsoft.com . Consultado el 23 de enero de 2023 .
  3. ^ "Método Object.ToString (sistema)". learn.microsoft.com . Consultado el 14 de junio de 2023 .
  4. ^ "Estructuras - Crystal". crystal-lang.org . Consultado el 21 de febrero de 2024 .
  5. ^ "Estructuras, uniones - Lenguaje de programación D". dlang.org . Consultado el 30 de mayo de 2023 .
  6. ^ "El lenguaje de programación Apache Groovy - Orientación a objetos". groovy-lang.org . Consultado el 24 de diciembre de 2023 .
  7. ^ "Newtype - HaskellWiki". wiki.haskell.org . Consultado el 18 de junio de 2023 .
  8. ^ "Clases de registro". Centro de ayuda de Oracle . Consultado el 24 de enero de 2023 .
  9. ^ "JSON.stringify() - JavaScript | MDN". developer.mozilla.org . Consultado el 23 de enero de 2023 .
  10. ^ "Object.freeze() - JavaScript | MDN". developer.mozilla.org . Consultado el 23 de enero de 2023 .
  11. ^ "Object.prototype.toString() - JavaScript | MDN". developer.mozilla.org . Consultado el 23 de enero de 2023 .
  12. ^ "Object.prototype.valueOf() - JavaScript | MDN". developer.mozilla.org . Consultado el 23 de enero de 2023 .
  13. ^ "Tipos · El lenguaje Julia". docs.julialang.org . Consultado el 30 de mayo de 2023 .
  14. ^ "Clases en línea | Kotlin". Ayuda de Kotlin . Consultado el 23 de enero de 2023 .
  15. ^ "Manual de Nim". nim-lang.org . Consultado el 4 de agosto de 2023 .
  16. ^ "Nim by Example - Tipos distintos". nim-by-example.github.io . Consultado el 4 de agosto de 2023 .
  17. ^ "PHP: Métodos mágicos - Manual" www.php.net . Consultado el 23 de enero de 2023 .
  18. ^ "PHP: JsonSerializable::jsonSerialize - Manual" www.php.net . Consultado el 23 de enero de 2023 .
  19. ^ "PHP: Palabra clave final - Manual" www.php.net . Consultado el 23 de enero de 2023 .
  20. ^ "PHP: Traits - Manual" www.php.net . Consultado el 2 de mayo de 2023 .
  21. ^ "dataclasses — Clases de datos". Documentación de Python . Python Software Foundation . Consultado el 23 de enero de 2023 .
  22. ^ "3. Modelo de datos". Documentación de Python . Python Software Foundation . Consultado el 12 de junio de 2023 .
  23. ^ "Tiping — Soporte para sugerencias de tipos". Documentación de Python . Python Software Foundation . Consultado el 17 de junio de 2023 .
  24. ^ "Datos de clase - Documentación para Ruby 3.3". docs.ruby-lang.org . Consultado el 6 de febrero de 2023 .
  25. ^ "Nuevo tipo de expresión idiomática: Rust con ejemplos". doc.rust-lang.org . Consultado el 18 de junio de 2023 .
  26. ^ "Depuración en std::fmt - Rust". doc.rust-lang.org . Consultado el 23 de enero de 2023 .
  27. ^ "PartialEq en std::cmp - Rust". doc.rust-lang.org . Consultado el 23 de enero de 2023 .
  28. ^ "Clases de casos". Documentación de Scala . Consultado el 15 de mayo de 2023 .
  29. ^ "CustomStringConvertible". Documentación para desarrolladores de Apple . Consultado el 5 de mayo de 2023 .
  30. ^ "Documentación". docs.swift.org . Consultado el 4 de mayo de 2023 .
  31. ^ "Estructuras | zig.guide". zig.guide . 20 de abril de 2024 . Consultado el 15 de octubre de 2024 .
  32. ^ "Documentación - El lenguaje de programación Zig" . Consultado el 15 de octubre de 2024 .
  • https://wiki.c2.com/?PrimitiveObsession
Obtenido de "https://es.wikipedia.org/w/index.php?title=Identificador_fuertemente_tipificado&oldid=1254328802"