Como posso forçar um C # construtor para ser uma fábrica?
-
13-09-2019 - |
Pergunta
O código abaixo é composto por duas classes | :
- SmartForm (classe modelo simples)
- SmartForms (classe plural que contém uma coleção de SmartForm Objects)
Eu quero ser capaz de criar uma instância ambas as classes singular e plural assim (ou seja, eu não quero um GetSmartForm método factory ()):
SmartForms smartForms = new SmartForms("all");
SmartForm smartForm = new SmartForm("id = 34");
Para consolidar a lógica, apenas a classe plural deve acessar a base de dados . A classe singular, quando perguntado para criar uma instância própria, simplesmente instanciar uma classe plural, em seguida, escolher o objeto para fora da coleção do objeto plural e tornar esse objeto .
Como posso fazer isso? Tentei atribuir o objeto para this
o que não trabalho.
using System.Collections.Generic;
namespace TestFactory234
{
public class Program
{
static void Main(string[] args)
{
SmartForms smartForms = new SmartForms("all");
SmartForm smartForm = new SmartForm("id = 34");
}
}
public class SmartForm
{
private string _loadCode;
public string IdCode { get; set; }
public string Title { get; set; }
public SmartForm() {}
public SmartForm(string loadCode)
{
_loadCode = loadCode;
SmartForms smartForms = new SmartForms(_loadCode);
//this = smartForms.Collection[0]; //PSEUDO-CODE
}
}
public class SmartForms
{
private string _loadCode;
public List<SmartForm> _collection = new List<SmartForm>();
public List<SmartForm> Collection
{
get
{
return _collection;
}
}
public SmartForms(string loadCode)
{
_loadCode = loadCode;
Load();
}
//fills internal collection from data source, based on "load code"
private void Load()
{
switch (_loadCode)
{
case "all":
SmartForm smartFormA = new SmartForm { IdCode = "customerMain", Title = "Customer Main" };
SmartForm smartFormB = new SmartForm { IdCode = "customerMain2", Title = "Customer Main2" };
SmartForm smartFormC = new SmartForm { IdCode = "customerMain3", Title = "Customer Main3" };
_collection.Add(smartFormA);
_collection.Add(smartFormB);
_collection.Add(smartFormC);
break;
case "id = 34":
SmartForm smartForm2 = new SmartForm { IdCode = "customerMain2", Title = "Customer Main2" };
_collection.Add(smartForm2);
break;
default:
break;
}
}
}
}
Solução
Ele não tem que ser exatamente o mesmo objeto, ele só tem que parecem ser o mesmo para observadores externos. Se você copiar todos os dados de um objeto para outro, ele vai fazer a mesma coisa.
public SmartForm(string loadCode)
{
_loadCode = loadCode;
SmartForms smartForms = new SmartForms(_loadCode);
this.IdCode = smartForms[0].IdCode;
this.Title = smartForms[0].Title;
}
Outras dicas
Vocês não pode obter um objeto para "tornar-se" outro.
Use métodos estáticos em vez de construtores (e fazer os construtores private / interna / o que quer para que apenas os métodos estáticos pode acessá-los). Existem inúmeras vantagens de se utilizar métodos estáticos sobre construtores:
- Você pode retornar nulo se apropriado
- Você pode retornar um objeto existente, se necessário
- Você pode fazer muito trabalho e então chamar um construtor simples que apenas define campos
O lado negativo é que eles não trabalham com C initializers # recolha / objetos: (
Um alternativa aos métodos estáticos (que não funcionam bem com injeção de dependência, na verdade) é ter um métodos distintos de fábrica e de instância chamada sobre isso.
Você não pode. Microsoft faz isso através da definição de um public static método Create () em vez. Ver, por exemplo WebRequest e HttpWebRequest no System.Net namespace. Eu sugiro que você faça o mesmo.
Faça o construtor da classe base interna ou privada, por isso não pode ser instanciado diretamente. Ou ainda melhor, torná-lo uma classe abstrata. Fazer uso dos construtores escondidos em sua implementação Create ().
Você poderia usar um internal
ou modificador protected
para o construtor, em vez de public
. Tal que:
public SmartForm() {}
public SmartForm(string loadCode)
{
_loadCode = loadCode;
SmartForms smartForms = new SmartForms(_loadCode);
//this = smartForms.Collection[0]; //PSEUDO-CODE
}
torna-se:
internal SmartForm() {}
internal SmartForm(string loadCode)
{
_loadCode = loadCode;
SmartForms smartForms = new SmartForms(_loadCode);
//this = smartForms.Collection[0]; //PSEUDO-CODE
}
Você poderia fazer uma classe privada chamada SmartFormData
, e colocar todos os valores para ele.
Faça a classe plural SmartForms
manter uma coleção desses objetos, e fazer o construtor singular SmartForm
localizar a instância SmartFormData direito em SmartForms
plural.
Em seguida, fazer todos os imóveis em SmartForm
singular buscar seus valores de SmartFormData
No entanto, a melhor maneira de fazer isso é ter um construtor privado e usar um método de fábrica.
Existe uma razão que você tem que usar um construtor?