Спросите себя, кто они и почему у нас есть. Они оба существуют, чтобы создать экземпляр объекта.
ElementarySchool school = new ElementarySchool();
ElementarySchool school = SchoolFactory.Construct(); // new ElementarySchool() inside
Пока нет разницы. Теперь представьте, что у нас есть разные типы школ, и мы хотим перейти от использования ElementarySchool к HighSchool (который получен из ElementarySchool или реализует тот же интерфейс ISchool, что и ElementarySchool). Изменение кода было бы:
HighSchool school = new HighSchool();
HighSchool school = SchoolFactory.Construct(); // new HighSchool() inside
В случае интерфейса у нас было бы:
ISchool school = new HighSchool();
ISchool school = SchoolFactory.Construct(); // new HighSchool() inside
Теперь, если у вас есть этот код в нескольких местах, вы можете видеть, что использование фабрики метод может быть довольно дешевым, поскольку после того, как вы измените заводский метод, который вы сделали (если мы используем второй пример с интерфейсами).
И это основное отличие и преимущество. Когда вы начинаете работать с сложными иерархиями классов и хотите динамически создавать экземпляр класса из такой иерархии, вы получаете следующий код. Затем фабричные методы могут принимать параметр, который сообщает методу, какой конкретный экземпляр должен быть создан. Предположим, у вас есть класс MyStudent, и вам нужно создать экземпляр соответствующего объекта ISchool, чтобы ваш ученик был членом этой школы.
ISchool school = SchoolFactory.ConstructForStudent(myStudent);
Теперь у вас есть одно место в вашем приложении, которое содержит бизнес-логику, которая определяет, какой объект ISchool создается для разных объектов IStudent.
Итак - для простых классов (объекты значений, и т. д.) конструктор просто прекрасен (вы не хотите перенастраивать свое приложение), но для сложных классов иерархии предпочтительным является заводский метод.
Таким образом, вы следуете первому принципу дизайна из группы из четырех книг «Программа на интерфейс, а не на реализацию».
Попробуйте это:
// add a reference to the System.Management assembly and
// import the System.Management namespace at the top in your "using" statement.
// Then in a method, or on a button click:
ManagementObjectSearcher theSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive WHERE InterfaceType='USB'");
foreach (ManagementObject currentObject in theSearcher.Get())
{
ManagementObject theSerialNumberObjectQuery = new ManagementObject("Win32_PhysicalMedia.Tag='" + currentObject["DeviceID"] + "'");
MessageBox.Show(theSerialNumberObjectQuery["SerialNumber"].ToString());
}
Решение с помощью Win32 описано здесь
Редактирование: исходная ссылка, кажется, пропала. Вышеупомянутое является кэшируемой копией, и автор также записал некоторый пример кода в VB.Net, который является все еще онлайн здесь .