Как я могу заставить конструктор C # быть фабрикой?
-
13-09-2019 - |
Вопрос
Приведенный ниже код состоит из два класса:
- Интеллектуальная форма (класс простой модели)
- Интеллектуальные формы (множественный класс , содержащий коллекцию Интеллектуальная форма объекты)
Я хочу иметь возможность создавать экземпляры как единственных, так и множественных классов вот так (т.е.Мне не нужен заводской метод GetSmartForm()):
SmartForms smartForms = new SmartForms("all");
SmartForm smartForm = new SmartForm("id = 34");
Для закрепления логики, доступ к базе данных должен иметь только множественный класс.Единственный класс, когда его попросят создать экземпляр самого себя, просто создаст экземпляр множественного класса, затем выберет один объект из коллекции множественного объекта и станьте этим объектом.
Как мне это сделать? Я попытался присвоить объект this
что не работает.
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;
}
}
}
}
Решение
Это не обязательно должен быть точно такой же объект, он просто должен казаться одинаковым внешним наблюдателям.Если вы скопируете все данные из одного объекта в другой, это приведет к тому же результату.
public SmartForm(string loadCode)
{
_loadCode = loadCode;
SmartForms smartForms = new SmartForms(_loadCode);
this.IdCode = smartForms[0].IdCode;
this.Title = smartForms[0].Title;
}
Другие советы
Вы не можете заставить один объект "стать" другим.
Используйте статические методы вместо конструкторов (и сделайте конструкторы закрытыми / внутренними / какими угодно, чтобы только статические методы могли получить к ним доступ).Использование статических методов вместо конструкторов имеет множество преимуществ:
- Вы можете вернуть null, если это уместно
- Вы можете вернуть существующий объект, если это необходимо
- Вы можете проделать много работы и тогда вызовите простой конструктор, который просто устанавливает поля
Недостатком является то, что они не работают с инициализаторами коллекции / объекта C # : (
Альтернативой статическим методам (которые, по общему признанию, плохо работают с внедрением зависимостей) является создание отдельной фабрики и вызов методов экземпляра на ней.
Ты не можешь.Microsoft делает это, определяя вместо этого общедоступный статический метод Create().Смотрите, например, WebRequest и HttpWebRequest в системе.Пространство имен Net.Я предлагаю вам сделать то же самое.
Сделайте конструктор базового класса внутренним или закрытым, чтобы его нельзя было создать напрямую.Или еще лучше, сделайте это абстрактным классом.Используйте скрытые конструкторы в вашей реализации Create().
Вы могли бы использовать internal
или protected
модификатор для конструктора, вместо public
.Такой , что:
public SmartForm() {}
public SmartForm(string loadCode)
{
_loadCode = loadCode;
SmartForms smartForms = new SmartForms(_loadCode);
//this = smartForms.Collection[0]; //PSEUDO-CODE
}
становится:
internal SmartForm() {}
internal SmartForm(string loadCode)
{
_loadCode = loadCode;
SmartForms smartForms = new SmartForms(_loadCode);
//this = smartForms.Collection[0]; //PSEUDO-CODE
}
Вы могли бы создать частный класс под названием SmartFormData
, и вложите в него все значения.
Сделайте так, чтобы SmartForms
множественный класс поддерживает коллекцию этих объектов и создает SmartForm
единственный конструктор найдите нужный экземпляр SmartFormData в SmartForms
множественное число.
Затем создайте все свойства в SmartForm
единственное число извлекает их значения из SmartFormData
Однако лучший способ сделать это - иметь частный конструктор и использовать фабричный метод.
Есть ли причина, по которой вы должны использовать конструктор?