¿Por qué debemos hacer que el constructor sea privado en clase? Como siempre necesitamos que el constructor sea público.
134
Algunas razones por las que puede necesitar un constructor privado:
final
a nivel de clase. Poner un constructor privado es prácticamente inútil por este motivo.final
. Esto es lo que hizo Sun para la clase String, y una porción razonable de la API que no debe extenderse.Al proporcionar un constructor privado, evita que se creen instancias de clase en cualquier lugar que no sea esta misma clase. Existen varios casos de uso para proporcionar dicho constructor.
A. Sus instancias de clase se crean en un
static
método. Elstatic
método se declara comopublic
.B. Tu clase es un singleton . Esto significa que no existe más de una instancia de su clase en el programa.
C. (Solo se aplica al próximo estándar C ++ 0x) Tiene varios constructores. Algunos de ellos están declarados
public
, otrosprivate
. Para reducir el tamaño del código, los constructores públicos 'llaman' a los constructores privados que a su vez hacen todo el trabajo. Suspublic
constructores se denominan así constructores delegadores :D. Desea limitar la copia de objetos (por ejemplo, debido al uso de un recurso compartido):
E. Tu clase es una clase de utilidad . Eso significa que solo contiene
static
miembros. En este caso, nunca se debe crear una instancia de objeto en el programa.fuente
Dejar una "puerta trasera" que permita que otra clase / función de amigo construya un objeto de una manera prohibida para el usuario. Un ejemplo que viene a la mente sería un contenedor que construye un iterador (C ++):
fuente
friend
donde no está garantizado, y hay muchos casos en los que es una mala idea. Lamentablemente, el mensaje ha sido muy bien recibido, y muchos desarrolladores nunca aprenden el idioma lo suficientemente bien como para comprender que el uso ocasionalfriend
no solo es aceptable, sino preferible . Su ejemplo fue solo un caso así. El acoplamiento fuerte deliberado no es delito, es una decisión de diseño.Todos están atrapados en lo de Singleton, wow.
Otras cosas:
fuente
Esto puede ser muy útil para un constructor que contiene código común; los constructores privados pueden ser llamados por otros constructores, usando 'this (...);' notación. Al hacer el código de inicialización común en un constructor privado (o protegido), también está dejando explícitamente claro que solo se llama durante la construcción, lo que no es así si fuera simplemente un método:
fuente
Hay algunos casos en los que es posible que no desee utilizar un constructor público; por ejemplo si quieres una clase singleton.
Si está escribiendo un ensamblado utilizado por terceros, podría haber una serie de clases internas que solo desea que su ensamblado cree y que los usuarios de su ensamblado no puedan crear instancias.
fuente
Esto garantiza que usted (la clase con constructor privado) controle cómo se llama al contructor.
Un ejemplo: un método de fábrica estático en la clase podría devolver objetos a medida que el método de fábrica elija asignarlos (como una fábrica de singleton, por ejemplo).
fuente
También podemos tener un constructor privado, para prevenir la creación del objeto solo por una clase específica (por razones de seguridad).
Una forma de hacerlo es tener una clase de amigos.
Ejemplo de C ++:
Nota: Nota: Solo ClientClass (ya que es amigo de SecureClass) puede llamar al Constructor de SecureClass.
fuente
Estos son algunos de los usos del constructor privado:
fuente
cuando no desea que los usuarios creen instancias de esta clase o creen una clase que herede esta clase, como
java.lang.math
, todas las funciones en este paquete sonstatic
, todas las funciones se pueden invocar sin crear una instanciamath
, por lo que el constructor se anuncia como estático .fuente
Si es privado, no puede llamarlo ==> no puede crear una instancia de la clase. Útil en algunos casos, como un singleton.
Hay una discusión y algunos ejemplos más aquí .
fuente
Vi una pregunta tuya que abordaba el mismo problema.
Simplemente, si no desea permitir que los demás creen instancias, mantenga el constructor dentro de un alcance limitado. La aplicación práctica (un ejemplo) es el patrón singleton.
fuente
No deberías hacer que el constructor sea privado. Período. Hazlo protegido, para que puedas extender la clase si lo necesitas.
Editar: Estoy de acuerdo con eso, no importa cuántos votos negativos arrojes a esto. Estás cortando el potencial para el desarrollo futuro del código. Si otros usuarios o programadores están realmente decididos a extender la clase, simplemente cambiarán el constructor a protegido en código fuente o bytecode. No habrá logrado nada más que hacer su vida un poco más difícil. Incluye una advertencia en los comentarios de tu constructor y déjalo así.
Si se trata de una clase de utilidad, la solución más simple, más correcta y más elegante es marcar toda la clase como "estática final" para evitar la extensión. No sirve de nada simplemente marcar el constructor privado; un usuario realmente determinado siempre puede usar la reflexión para obtener el constructor.
Usos válidos:
protected
constructor es forzar el uso de métodos de fábrica estáticos, que le permiten limitar la creación de instancias o agrupar y reutilizar recursos caros (conexiones de base de datos, recursos nativos).fuente
Constructor es privado para algún propósito, como cuando necesita implementar singleton o limitar el número de objetos de una clase. Por ejemplo, en la implementación de singleton tenemos que hacer que el constructor sea privado
Nuevamente, si desea limitar la creación de objetos hasta 10, use lo siguiente
Gracias
fuente
Puedes tener más de un constructor. C ++ proporciona un constructor predeterminado y un constructor de copia predeterminado si no proporciona uno explícitamente. Supongamos que tiene una clase que solo se puede construir utilizando algún constructor parametrizado. Quizás inicializó variables. Si un usuario usa esta clase sin ese constructor, puede causar un sinfín de problemas. Una buena regla general: si la implementación predeterminada no es válida, haga que tanto el constructor predeterminado como el de copia sean privados y no proporcione una implementación:
Use el compilador para evitar que los usuarios usen el objeto con los constructores predeterminados que no son válidos.
fuente
Citando desde Java efectivo , puede tener una clase con un constructor privado para tener una clase de utilidad que defina constantes (como campos finales estáticos).
( EDITAR: según el comentario, esto es algo que podría ser aplicable solo con Java, no sé si esta construcción es aplicable / necesaria en otros lenguajes OO (por ejemplo, C ++))
Un ejemplo como el siguiente:
EDIT_1 : Nuevamente, la explicación a continuación es aplicable en Java: (y haciendo referencia al libro, Java efectivo )
Una instanciación de la clase de utilidad como la siguiente, aunque no es dañina, no sirve para nada, ya que no están diseñados para ser instanciados.
Por ejemplo, supongamos que no hay un constructor privado para las constantes de clase. Un fragmento de código como el siguiente es válido pero no transmite mejor la intención del usuario de la clase Constantes
en contraste con el código como
También creo que un constructor privado transmite mejor la intención del diseñador de la clase Constantes (digamos).
Java proporciona un constructor público sin parámetros predeterminado si no se proporciona ningún constructor, y si su intención es evitar la creación de instancias, se necesita un constructor privado.
No se puede marcar una clase de nivel superior estática e incluso se puede instanciar una clase final.
fuente
Las clases de utilidad podrían tener constructores privados. Los usuarios de las clases no deberían poder crear instancias de estas clases:
fuente
Es posible que desee evitar que una clase sea instanciada libremente. Vea el patrón de diseño singleton como ejemplo. Para garantizar la singularidad, no puede dejar que nadie cree una instancia de ella :-)
fuente
Uno de los usos importantes es en la clase SingleTon
También es adecuado, si su clase solo tiene métodos estáticos. es decir, nadie necesita crear una instancia de tu clase
fuente
Realmente es una razón obvia: desea construir un objeto, pero no es práctico hacerlo (en términos de interfaz) dentro del constructor.
El
Factory
ejemplo es bastante obvio, déjame demostrar elNamed Constructor
idioma.Digamos que tengo una clase
Complex
que puede representar un número complejo.La pregunta es: ¿el constructor espera las partes reales e imaginarias, o espera la norma y el ángulo (coordenadas polares)?
Puedo cambiar la interfaz para que sea más fácil:
Esto se llama
Named Constructor
modismo: la clase solo se puede construir desde cero al indicar explícitamente qué constructor queremos usar.Es un caso especial de muchos métodos de construcción. Los patrones de diseño son un buen número de formas de acumulación de objetos:
Builder
,Factory
,Abstract Factory
, ... y un constructor privado se asegurará de que el usuario se ve limitada correctamente.fuente
Además de los usos más conocidos ...
Para implementar el patrón Object Object , que resumiría como:
Si desea implementar una función usando un objeto, y el objeto no es útil fuera de hacer un cálculo único (mediante una llamada al método), entonces tiene un Objeto desechable . Puede encapsular la creación de objetos y la llamada al método en un método estático, evitando este antipatrón común:
... reemplazándolo con una llamada de función (espacio de nombres):
La persona que llama nunca necesita saber o preocuparse de que esté utilizando un objeto internamente, produciendo una interfaz más limpia y evitando que la basura del objeto cuelgue o el uso incorrecto del objeto.
Por ejemplo, si desea dividir un cálculo entre métodos
foo
,bar
yzork
, por ejemplo, para la participación del estado sin tener que pasar muchos valores dentro y fuera de funciones, se podría implementar de la siguiente manera:Este patrón de objeto de método se da en Smalltalk Best Practice Patterns , Kent Beck, páginas 34–37, donde es el último paso de un patrón de refactorización, que termina:
Esto difiere significativamente de los otros ejemplos aquí: la clase es instanciable (a diferencia de una clase de utilidad), pero las instancias son privadas (a diferencia de los métodos de fábrica, incluidos los singletons, etc.) y pueden vivir en la pila, ya que nunca escapan.
Este patrón es muy útil en la OOP de abajo hacia arriba, donde los objetos se usan para simplificar la implementación de bajo nivel, pero no necesariamente están expuestos externamente, y contrasta con la OOP de arriba hacia abajo que a menudo se presenta y comienza con interfaces de alto nivel.
fuente
A veces es útil si desea controlar cómo y cuándo se crean (y cuántas) instancias de un objeto.
Entre otros, utilizados en patrones:
fuente
El uso de constructores privados también podría ser aumentar la legibilidad / mantenibilidad frente al diseño dirigido por el dominio. De "Microsoft .NET - Aplicaciones de arquitectura para la empresa, 2ª edición":
Cita: "Hay dos problemas aquí. Primero, cuando se mira el código, uno apenas puede adivinar lo que está sucediendo. Se está creando una instancia de OrderRequest, pero ¿por qué y con qué datos? ¿Qué es 1234? Esto lleva al segundo problema: está violando el lenguaje ubicuo del contexto acotado. El lenguaje probablemente dice algo como esto: un cliente puede emitir una solicitud de pedido y se le permite especificar un ID de compra. Si ese es el caso, esta es una mejor manera de obtener una nueva instancia de OrderRequest : "
dónde
No estoy abogando por esto para cada clase, pero para el escenario DDD anterior, creo que tiene mucho sentido evitar la creación directa de un nuevo objeto.
fuente