Уже более года разработчики присылают мне проблемный код из своих проектов, задают вопросы по архитектуре и тестированию. Проблемы часто повторяются, как и подходы к их решению. Думаю неправильно, что решения остаются только между мной и автором кода в личной переписке.
Я решил открыть рубрику «Совершенный код». Каждую неделю буду выкладывать проблемный код, вопросы по архитектуре или тестированию, которые вы мне присылаете. Вы можете находить проблемы в коде и описывать пути их решения. Через неделю я выложу лучшие советы со ссылкой на авторов и возможно своими дополнениями. Авторы решений, оставляйте, пожалуйста, свои контакты (сайты, блоги), чтобы я мог на вас ссылаться.
Начали!
Приложение написано на ASP.NET MVC. Мне прислали небольшой кусочек кода, связанный с редактирование отчёта. У автора возникли проблемы с изменением этого кода, написанием на него тестов и работой с моделью (M-V-C).
Контроллер ReportersController
1: public class ReportersController : Controller
2: {
3: Linq2SqlDataContext dataContext;
4:
5: public ReportersController()
6: {
7: dataContext = new Linq2SqlDataContext();
8: }
9:
10: // ...
11:
12: // форма редактирования
13: public ActionResult Edit(int id)
14: {
15: var item = dataContext.Reporters.FirstOrDefault(x => x.Id == id);
16: return View(new ReporterFormViewModel(item));
17: }
18:
19: [HttpPost]
20: public ActionResult Edit(int id, Reporter reporter, string saveAndExit, string saveAndStay)
21: {
22: var item = dataContext.Reporters.FirstOrDefault(x => x.Id == id);
23:
24: if (ModelState.IsValid)
25: {
26: try
27: {
28: UpdateModel(item, "reporter");
29:
30: dataContext.SubmitChanges();
31:
32: if (saveAndExit == null)
33: return RedirectToAction("Edit", new { id });
34:
35: return RedirectToAction("Index");
36: }
37: catch (Exception ex)
38: {
39: ModelState.AddModelError("formReport", ex.Message);
40:
41: return View(new ReporterFormViewModel(reporter));
42: }
43: }
44:
45: return View(new ReporterFormViewModel(reporter));
46: }
47: }
Модель ReporterFormViewModel
1: public class ReporterFormViewModel
2: {
3: public ReporterFormViewModel() : this(new Reporter() { CreatedDate = DateTime.Now })
4: {
5: }
6:
7: public ReporterFormViewModel(Reporter reporter)
8: {
9: Reporter = reporter;
10:
11: InitCollections();
12: }
13:
14: private void InitCollections()
15: {
16: var dataContext = new Linq2SqlDataContext();
17:
18: Publications = dataContext.Publications.Select(x => new SelectListItem() {
19: Value = x.Id.ToString(),
20: Text = x.Name
21: });
22: }
23:
24: public IEnumerable<SelectListItem> Publications { get; set; }
25:
26: public Reporter Reporter { get; set; }
27: }
Тестов к коду, к сожалению, нет. Да-да, я понимаю, что делать рефакторинг без тестов довольно сложно.
Хочу заметить, что разработчики, которые могут признать, что в их коде есть проблемы, имеют все шансы стать лучше и узнать что-то новое. Надо иметь смелость, чтобы просить помощи. Поэтому в комментариях к коду приветствуется конструктив и позитив!
Разбор решения к выпуску №1