2013-03-28 5 views
0

Пожалуйста, обратите внимание на код ниже:VB.NET - Создание объектов на каждом цикле

Public Sub MassDelete() 
     Dim objCommand As SqlCommand 
     Dim objCon As SqlConnection 
     Dim objDR As SqlDataReader 
     Try 
      Dim _ConString As String = "Data Source=IANSCOMPUTER;Initial Catalog=Test5;Integrated Security=True;MultipleActiveResultSets=true" 
      objCon = New SqlConnection(_ConString) 
      Using objCon 
        objCommand = New SqlCommand("SELECT * FROM Person WHERE StartDate <= dateadd(-6,year," & Now & ")") 
       objCommand.Connection = objCon 
       Using objCommand 
        objCon.Open() 
        objDR = objCommand.ExecuteReader 
        Do While objDR.Read 
         'Send ID over web service 
         'Send email to person 
         'Add log entry to log file 
        Loop 
        objDR.Close() 
       End Using 
      End Using 
     Catch ex As Exception 
      Throw 
     Finally 

     End Try 

Я вижу много кода, как это от предыдущего разработчика то есть одна функция, которая петлями через таблицу, например, лицом, транспортным средством, учетной записью и т. д. и совершает действия над тысячами или в некоторых случаях миллионами записей. В случае вышесказанного, лица удаляются через шесть лет после даты начала. Для каждой итерации цикла while существует три действия: отправьте идентификатор по веб-службе, отправьте электронное письмо человеку и добавьте запись журнала в файл журнала. Я пытаюсь реорганизовать этот код, поскольку я продолжаю разработку рассматриваемой системы.

Я считаю, что должны быть разные классы для Email, WebService и Log и вместо выполнения всей работы в функции MassDelete; работа будет распространена среди классов, например. письмо будет отправлено из класса электронной почты. Существуют ли какие-либо ограничения на создание объектов для WebService, Email и Log для каждой итерации цикла и использования их переменных экземпляра (в Person может быть миллион записей)?

+0

FWIW: используйте ['Using'] (http://msdn.microsoft.com/en-us/library/htd05whh.aspx). Одна из причин держать его отправленным из одного места (даже если «код отправки» находится в другом классе) заключается в том, что транзакция * может использоваться *. И нет, создание объекта дешево. Однако действительно ли нужно, чтобы объект «отправить электронную почту» * был новым экземпляром или он просто предоставлял такую ​​услугу, как «SendEmail (адрес, тема, сообщение)»? В этом случае было бы бессмысленно сделать его классом «EmailBoundToAnAddress». Теперь код WebService/Logging * * привязан к чему-то, но не тот, который меняет каждый цикл. – 2013-03-28 22:01:56

+0

Спасибо. Я обновил вопрос с помощью операторов. Я не понимаю оставшуюся часть вашего последнего комментария. Не могли бы вы пояснить или опубликовать ответ? – w0051977

+0

Какая часть? (Я обычный редактор.) – 2013-03-28 22:07:11

ответ

1

Хотя создание объекта является дешевым - то есть, создание новых объектов за петлю не будет иметь общее влияние на производительности (в зависимости от того, как много работы, конструктор делает) - новые объекты, должны быть сделаны только тогда, когда это семантический правильным/смысла для этого.

В этом случае я защищаю хранение услуги отдельно от данных (например, Person записи), которая просто передается в определенные вызовы служб. Я действительно не знаю VB.NET (я использую C#), поэтому при необходимости настройте синтаксис.

' Note that the services are bound to some things - but NOT people 
' I recommend using DI/IoC (Dependency Injection) 
' Also the Logger is generally a larger application-wide service 
Var mailer = New EmailService(SMTPServerString, SMTPTimeout) 
Var ws = New WebService(WSEndpoint) 
Var log = New LoggerService() 
Var objCon = OpenConnection() 

Using objCon 
    Var objCommand = objCon.CreateCommand(..); 
    Using objCommand 
     Var objDR = objCommand.ExecuteReader 
     Do While objDR.Read 
      ' Person different per loop 
      Var person = New Person(objDR) 
      ' But services are the same and are not "bound" to a person 
      ws.RecordDelete(person.Id) 
      mailer.Send(person.Email, Subject, Message) 
      log.Log(Log.Information, "Deleted person: " & person.Id) 
     Loop 
    End Using 
End Using 

Конечно, этот код по-прежнему не является очень отказоустойчивым или распространяемым. Очереди сообщений (например, AMPQ), возможно, стоит изучить.

+0

Спасибо +1. Я вижу, что почтовая программа и ws содержат общие (статические) функции, то есть Send and RecordDelete, соответственно. Есть ли какая-либо техническая причина не использовать переменные экземпляра, например. для параметров .SEND, т. е. person.Email, Subject и Message – w0051977

+0

@ w0051977 ** Нет статических функций ** - методы экземпляра: D И да, потому что это путает * службу * с сущностью домена (* данные *). Сохраняя отдельные сервисы, они легко могут использоваться повторно без какой-либо связи, и, сохраняя * данные * из сервиса, мы можем упростить IoC/DI (что является большой победой). – 2013-03-28 22:36:49

+0

да, пожалуйста, проигнорируйте первую часть моего предыдущего комментария. Есть ли какая-либо техническая причина не использовать переменные экземпляра, например. для параметров .SEND, т.е. person.Email, Subject и Message – w0051977

Смежные вопросы