Это relativility легкий видеть ошибку архитектуры, когда проект закончен. X дал нам проблемы безопасности, или Y дал нам большую дополнительную работу. Они пойманы в ретроспективах, но было бы хорошо поймать их ранее.
Мы - планирование выполнения обзоров архитектуры, прежде чем кодирование запустится.
Один путь состоит в том, чтобы только заставить архитектора представлять проект и видеть, можем ли мы найти дефекты в дизайне.
У кого-либо есть больше структурированного подхода, возможно, с, "Вы думали" или, "Как Вы собираетесь сделать" контрольный список.
Я думал о чем-то как:
Дополнительные пункты для добавления в ваш список, без особого порядка:
Вы должны использовать хорошо известные шаблоны и, возможно, даже архитектурные фреймворки, чтобы уменьшить вероятность возникновения непредвиденных ситуаций.
Относительно легко увидеть ошибки архитектуры по завершении проекта, но это заложено в самой природе того, что мы делаем.
Я считаю хорошей практикой постоянно делать обзоры архитектуры. Это не тот шаг, который вы просто «завершили».
Вы всегда можете определить собственное неявное преобразование:
implicit def funToOrdering[T,R <% Ordered[R]](f: T => R) = new Ordering[T] {
def compare(x: T, y: T) = f(x) compare f(y)
}
val list = ("a", 5) :: ("b", 3) :: ("c", 2) :: Nil
list.min { t: (String,Int) => t._2 } // (c, 2)
EDIT: Per @ Dario's comments.
Может быть более читаемым, если преобразование не было неявным, но с использованием функции «on»:
def on[T,R <% Ordered[R]](f: T => R) = new Ordering[T] {
def compare(x: T, y: T) = f(x) compare f(y)
}
val list = ("a", 5) :: ("b", 3) :: ("c", 2) :: Nil
list.min( on { t: (String,Int) => t._2 } ) // (c, 2)
-121--1370743- Чтобы максимально приблизиться к вашему примеру кода, вы можете ввести еще один уровень косвенности в виде IViewPopulator:
public interface IViewPopulator
{
void Populate(IView view);
}
Теперь вы можете реализовать SomeViewFactory так:
public class SomeViewFactory : ISomeViewFactory
{
private readonly IViewPopulator populator;
public SomeViewFactory(IViewPopulator populator)
{
if (populator == null)
{
throw new ArgumentNullException("populator");
}
this.populator = populator;
}
public IView CreateView()
{
IView view = new SomeView();
this.populator.Populate(view);
return view;
}
}
Это разделяет создание представлений и совокупность ViewModels, придерживаясь Принципа единой ответственности . В определенной степени это также является примером агрегирования услуг .
Теперь вы можете реализовать IViewPopulator как конкретный тип, который принимает нормальные зависимости:
public class SomeViewPopulator : IViewPopulator
{
private readonly IDependency dep;
public SomeViewPopulator(IDependency dep)
{
if (dep == null)
{
throw new ArgumentNullException("dep");
}
this.dep = dep;
}
public void Populate(IView view)
{
var vm = // Perhaps use this.dep to create an instance of IViewModel...
view.ViewModel = vm;
}
}
Вероятно, есть другие способы моделирования отношений между IView и IViewModel, но выше представлено одно возможное решение.
Ключ состоит в том, чтобы продолжать извлекать абстракции до тех пор, пока каждая из них не будет иметь четко определенную ответственность. Это упражнение на самом деле не о том, чтобы сделать код Container-agnostic вообще, но в конечном итоге о том, чтобы придерживаться принципов SOLID.
-121--2730529-Одним из важных проектов является документ с вариантами решения. Вы занимаетесь мозговым штурмом, собираете имеющуюся информацию, общаетесь с МСП, разговариваете с кем угодно и создаете таблицу для различных вариантов с достоинствами, недостатками, приблизительными затратами и оценками. Да, это упражнение является накладными расходами, но многие из тех проблем, которые вы описываете, будут известны, если вы это сделаете.
В конце рекомендует решение для управления с причинами и, возможно, высокоуровневой схемой архитектуры для визуализации решения.
Очевидно, что существует большое количество книг по этой теме (например, 97 вещей, которые должен знать архитектор). Вы можете найти исчерпывающий список аксиом здесь , и я бы посоветовал вам выбрать те, которые имеют смысл для ваших проектов, для вашего контрольного списка.
Изменения постоянны, убедитесь, что ваша архитектура адаптируется.
Пользовательский интерфейс - это то, что улучшает работу пользователей.
Полностью поделитесь своими знаниями об архитектуре со всеми.
Попробуйте, прежде чем внедрять.
Не злоупотребляйте шаблонами проектирования.