Clase PHP que se comporta como enumias -- php campo con enum camp codereview Relacionados El problema

PHP class that behaves like enums


4
vote

problema

Español

Soy relativamente nuevo en PHP y una de las cosas que extraño de otros idiomas son enumias. Después de mirar alrededor de algunas muestras sobre cómo puedo tener algo similar a ellos, se me ocurrió esta implementación. Quiero saber lo bueno que es, ¿cómo puede mejorarse o cualquier otra falla que pueda encontrar en ella? Está escrito en PHP 7.

Clase base

  abstract class BaseEnum {     private $value;      protected function __construct(string $value) {         $this->value = $value;     }      public function getValue(): string {         return $this->value;     }      public abstract static function parse(?string $value);      public abstract static function InitializeEnums(); }   

Esta es la clase base desde donde se hereda todas mis "enumias". En resumen, esta es una clase inmutable que sostiene un solo valor de cadena y un getter para él (internamente, todos los enumeres serán cadenas, se opongan a otros idiomas que a menudo son INTS). Hay un método abstracto que toma una cadena RAW y devuelve la instancia de enumeración correspondiente que debe implementarse caso por caso, así como un método de inicialización (ver más abajo para esto).

Clase de enumeración de hormigón

  class VoucherType extends BaseEnum {     private static $invoice;     private static $creditNote;     private static $advance;      public static function InitializeEnums() {         VoucherType::$invoice = new VoucherType("I");         VoucherType::$creditNote = new VoucherType("C");         VoucherType::$advance = new VoucherType("A");     }      public static function parse(?string $value): ?self {         if($value === VoucherType::$invoice->getValue()) return VoucherType::$invoice;         if($value === VoucherType::$creditNote->getValue()) return VoucherType::$creditNote;         if($value === VoucherType::$advance->getValue()) return VoucherType::$advance;         return null;     }      public static function invoice(): self {         return VoucherType::$invoice;     }     public static function creditNote(): self {         return VoucherType::$creditNote;     }     public static function advance(): self {         return VoucherType::$advance;     } } VoucherType::InitializeEnums();   

Esta es una de mis clases de enumio reales. Todo lo que hace es proporcionar los valores válidos fijos y los obturadores apropiados para cada uno. También implementa el análisis que parece a su vez. Almacena a los singletos de cada valor posible y aquellos son devueltos según sea necesario. La inicialización de los singletos se realiza a través del método InitializeEnums

Esto permite realizar comparaciones simples con valores "constantes" como $var == VoucherType::invoice()

, o para convertir a / desde la cadena con el manejo de valores no válidos apropiados (y reemplazados con nulos). Las variables siempre serán de este tipo de clase (y no simples cadenas) y la asignación / comparación funciona como se espera.

¿Cómo puedo mejorarlo y qué es bueno, malo o debería cambiarlo?

Original en ingles

I'm relatively new to PHP and one of the things I miss from other languages are enums. After looking around for some samples on how can I have somewhat similar to them, I came up with this implementation. I want to know how good is it, how can it be improved or any other flaws you can find in it. It's writen in PHP 7.

Base class

abstract class BaseEnum {     private $value;      protected function __construct(string $value) {         $this->value = $value;     }      public function getValue(): string {         return $this->value;     }      public abstract static function parse(?string $value);      public abstract static function InitializeEnums(); } 

This is the base class from where all my "enums" inherit. In short this is an immutable class that hold a single string value and a getter for it (internally all enums will be string, opposed to other languages that are often ints). There is an abstract method that takes a raw string and returns the matching enum instance that needs to be implemented in a case-by-case basis, as well as an initialization method (see below for this).

Concrete enum class

class VoucherType extends BaseEnum {     private static $invoice;     private static $creditNote;     private static $advance;      public static function InitializeEnums() {         VoucherType::$invoice = new VoucherType("I");         VoucherType::$creditNote = new VoucherType("C");         VoucherType::$advance = new VoucherType("A");     }      public static function parse(?string $value): ?self {         if($value === VoucherType::$invoice->getValue()) return VoucherType::$invoice;         if($value === VoucherType::$creditNote->getValue()) return VoucherType::$creditNote;         if($value === VoucherType::$advance->getValue()) return VoucherType::$advance;         return null;     }      public static function invoice(): self {         return VoucherType::$invoice;     }     public static function creditNote(): self {         return VoucherType::$creditNote;     }     public static function advance(): self {         return VoucherType::$advance;     } } VoucherType::InitializeEnums(); 

This is one of my real enum classes. All that it does is to provide the fixed valid values and appropriate getters for each one. Also implements the parse that looks each value in turn. It stores singletons of each possible value and those are returned as needed. The initialization of the singletons is done via the InitializeEnums method, which is called outside the class (a dirty trick to simulate a static constructor).

This enables to make simple comparisons with "constant" values like $var == VoucherType::invoice(), or to convert to/from string with appropriate invalid values handling (and replaced with nulls). Variables will always be from this class type (and not simple strings) and assignment/comparision works as expected.

How can I improve it and what's good, bad or should change about it?

     

Lista de respuestas

1
 
vote

Simularía el enumulación utilizando constantes de clase.

  class VoucherType {   const INVOICE = 0;   const CREDIT_NOTE = 1;   const ADVANCE = 2; }  $myType = VoucherType::INVOICE;   

Son accesibles desde cualquier lugar donde puede acceder a la clase, prácticamente en todas partes si lo usa (y debe) un autocargador.

Este es un patrón legible y conocido, pero hay opciones más sofisticadas, comenzando con splenum y terminando con php7-enum , pero me gusta la simplicidad de las constantes.

También usted es nuevo en PHP, le recomiendo que lea el código de otro para aprender y acostumbrarse al idioma.

 

I would simulate the enum using class constants.

class VoucherType {   const INVOICE = 0;   const CREDIT_NOTE = 1;   const ADVANCE = 2; }  $myType = VoucherType::INVOICE; 

They are accesible from everywhere you can access the class, virtually everywhere if you use (and you should) an autoloader.

This is a readable and well-known pattern but there are more sophisticated options, starting with SplEnum and ending with php7-enum, but I like the simplicity of the constants.

Also I you are new to PHP I recommend you to read other's code to learn and get used to the language.

 
 

Relacionados problema

4  Enum Class para unidades de peso  ( Enum class for weight units ) 
Tengo algunas clases de enumeración para unidades, como unidades de peso (kg y lb). Estoy traduciendo el código a Qt C ++ de Java, y me pregunto cuál es la me...

8  Usando las descripciones de Enum a la encuadernación de cadena / texto  ( Using enum descriptions to string text binding ) 
En mi aplicación WP8, necesito mostrar un par de botones de radio para que el usuario seleccione un valor de un enum . No quiero concojo hardco, ya sea el va...

2  Lanzar una enumeración con descripciones en un diccionario  ( Casting an enumeration with descriptions into a dictionary ) 
La enumeración en cuestión se basa en int , por lo que la siguiente extensión devuelve un Dictionary<int, string> del valor y la descripción de Enum. ¿Ha...

1  Enumeración de C # mejorada / `Enume`  ( Enhanced c enumeration enum ) 
Estoy desarrollando mi propio tipo de enumeración como SmartEnum pero intentando Para evitar que el usuario proporcione una definición de tipo recursivo d...

20  Construyendo una buena biblioteca de plantillas C ++ 11 - Tiempo compilado enumeró la matriz enumulada [cerrada]  ( Building a good c11 template library compile time checked enum array ) 
cerrado. Esta pregunta es off-topic . Actualmente no está aceptando respuestas. ¿Quieres ...

1  Clase de juego, escrito usando enums  ( Playing card class written using enums ) 
Escribí una clase de tarjeta A Mientras vuelvas a esta publicación aquí: Pregunta previa Sé que ha pasado mucho tiempo, pero recientemente regresé al proyec...

7  El picking pesaba valores enumerables al azar  ( Picking weighed enumerable values at random ) 
Tengo una serie de enumerables, y quiero elegir al azar un valor de uno de los enumerables para que cada valor tenga un cierto peso en el proceso de aleatoriz...

13  Cargando un combobox con un enumio y unido a él  ( Loading a combobox with an enum and binding to it ) 
Tengo el siguiente código para cargar una enumeración en un cuadro combinado unido, pero no estoy muy feliz con él. Preferiría almacenar el valor real 9988...

1  Nucleides enum biblioteca  ( Nuclides enum library ) 
Actualmente estoy desarrollando un programa en la física nuclear y me gustaría tener un acceso simple a todos los nucleidos. Especificaciones técnicas son: ...

8  Rubygem para enumias  ( Rubygem for enums ) 
Un poco de fondo primero. He estado trabajando en una aplicación de rieles bastante grandes que se convirtió rápidamente en un cero de reproducción para el có...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos