Тупой вопрос про Service-oriented Architecture

6yrop

Как в SOA реализуются арифметические расчеты "на лету"? Например, есть форма заказа. Указывается текущая цена на товар. Пользователь вводит количество товара. Требуется рассчитать сумму заказа, т.е. перемножить два числа, и показать пользователю.
1. Где это делается согласно SOA? на сервере? А если в заказе несколько товаров, скажем 20, будет 20 обращений на сервер?
2. Как это выглядит в коде? (покажите схематично). В объектно-ориентированной архитектуре эти расчеты были как метод класса, инкапсулирующего данные заказа:
 
 
public class Order
{
public decimal Price;

public int Quantity;

public decimal GetSum
{
return Price * Quantity;
}
}

Сколько классов будет в SOA?

Dasar

зачем классы?
один xml запрос, один xml-ответ.

6yrop

как на xml-е умножить два числа?

Dasar

> Где это делается согласно SOA? на сервере?
если в лоб, то на сервере, если важно удобство - то на клиенте
> А если в заказе несколько товаров, скажем 20, будет 20 обращений на сервер?
если нужна оперативность (ответ пользователю по мере ввода им инфы) - то да, 20.
иначе один.
> 2. Как это выглядит в коде?
ввели -> запрос на сервер -> посчитали -> получили ответ -> показали
Input xml
<Request>
<Tovar name="Apple" count='20'/>
<Tovar name="Lemon" count='10'/>
</Request>
output xml
<Answer>
<Tovar name="Apple" count='20' price='3.40'/>
<Tovar name="Lemon" count='10' price='2.70'/>
</Answer>

Dasar

> как на xml-е умножить два числа?
тупишь. xml никакого отношения к логике не имеет.
xml нужен только для того, чтобы описать вопросы и ответы.

6yrop

меня интересуют именно описание бизнес-логики, т.е. расчетов.

Dasar

сильно зависит от специфики задачи, и используемых языковых средств.
например, выше приведенную задачу можно решать на:
xslt
sql
процедурный язык
фя
ооп-язык
и т.д.

6yrop

 
например, выше приведенную задачу можно решать на:
xslt
sql

можно, но ОЧЕНЬ не удобно
в xslt/sql плохая поддержка ситуаций, когда одна формула ссылается на другую, например

public class Order
{
public decimal Price;

public int Quantity;

public decimal GetSum
{
return Price * Quantity;
}

public decimal GetTotalSum
{
return GetSum * (1 + 0.05);
}

}

попробуй написать это на xslt или чистом sql

6yrop

процедурный язык
ооп-язык

я не могу себе представить ситуацию, когда реализация на процедурном языке будет выигрывать по-сравнению с реализацией на ооп-языке. Ты можешь?

Dasar

в xslt - локальные переменные есть, поэтому проблем не вижу.
в sql можно через вложенный запрос извратнуться
ps
на практике, конечно, будет что-то такое:

Tovar_Result[] Calc(Tovar_Request[] tovars)
{
Tovar_Result[] result = new Tovar_Result[tovars.Length];
for (int i = 0; i < tovars.Count; ++i)
result[i] = new Tovar_result(tovars[i].Name, tovars[i].Count,
tovars[i].Count*GetPrice(tovars[i].Name);
return result;
}

Dasar

> Ты можешь?
как вариант: процедурный компилятор более вылизан (оптимизирован чем ооп-шный.
до недавнего времени - это предположение было точно актуально.

6yrop

например, выше приведенную задачу можно решать на:
фя

да вполне вероятно, что наиболее оптимально. Но сейчас говоря о SOA, обычно имеют ввиду современные платформы .NET/Java, пока там фя нет.

Dasar

> да вполне вероятно, что наиболее оптимально
имхо, наиболее оптимально: ООП с элементами фя, или Фя с элементами ООП.
потому что логику обычно удобно описывать как фя-преобразование, а элементы удобно описывать как объекты.

6yrop

в xslt - локальные переменные есть, поэтому проблем не вижу.
введение локальной переменной это и есть проблема, как код будет адаптироваться к вот таким изменениям:
1. Добавление GetTotalSum. В C# я просто добавил метод, ничего не меняя, а xslt придется ввести локальную переменную и переписать "метод" GetSum (теперь возвращает значение локальной переменной).
2. А если Price тоже станет расчетной величиной? В C# переменная заменятся на свойство и всё.
Вот такие вот мелочи при достаточно количестве расчетов превращаются в кошмар.

Dasar

> 1. Добавление GetTotalSum. В C# я просто добавил метод, ничего не меняя, а xslt придется ввести локальную
> переменную и переписать "метод" GetSum (теперь возвращает значение локальной переменной).
> 2. А если Price тоже станет расчетной величиной? В C# переменная заменятся на свойство и всё.
обе проблемы проще решать через инструментальную поддержку рефакторинга, чем с помощью языковых средств.

6yrop

обе проблемы проще решать через инструментальную поддержку рефакторинга, чем с помощью языковых средств.
в обоих случаях причин для рефакторинга нет, все изменения носят характер добавления функциональности. Почему такие добавления должны влиять на фрагменты кода, которые описывают другую (уже написанную) функциональность?

6yrop

Tovar_Result[] Calc(Tovar_Request[] tovars)
{
Tovar_Result[] result = new Tovar_Result[tovars.Length];
for (int i = 0; i < tovars.Count; ++i)
result[i] = new Tovar_result(tovars[i].Name, tovars[i].Count,
tovars[i].Count*GetPrice(tovars[i].Name);
return result;
}
1. т.е. отказываемся от инкапсуляции данных и методов?
2. На одну бизнес-сущность вводим два элемента программного кода Tovar_Request и Tovar_Result? Раздвоение связано лишь с тем, что приложение выполняется на двух машинах? где и когда мы получим выигрыш от такого раздвоения?
3. Все расчеты в одном методе? если добавиться GetTotalSum потребуется вносить изменения внутрь метода Calc?

Dasar

> Почему такие добавления должны влиять на фрагменты кода, которые описывают другую (уже написанную) функциональность?
основная причина: потому что только в сказках, каждая новая фича независима от уже написанного кода.
как раз основные потребности рефакторинга две:
1. нам нужно внести изменения, но в существующий код эти изменения будут вноситься коряво
2. мы внесли изменения и нам перестал нравиться код
т.е. рефакторинг как раз и происходит либо до внесения нового изменения, либо после.

Dasar

> 1. т.е. отказываемся от инкапсуляции данных и методов?
какая цель этой инкапсуляции, что это даст?
> 2. На одну бизнес-сущность вводим два элемента программного кода Tovar_Request и Tovar_Result?
я вижу две бизнес сущности
одна - это товар с ценой
другая - это товар без цены.
жирный класс - товар то с ценой, то без цены - имеет право тоже на жизнь, но код становится обычно более запутанный, потому что каждый раз приходится догадываться - сейчас мы работает с товаром с ценой, или без.
> 3. Все расчеты в одном методе?
небольшие - да
большие в несколько
> если добавиться GetTotalSum потребуется вносить изменения внутрь метода Calc?
скорее всего да, если нам это не понравиться, то надо будет чуть отрефакторить.
ps
основная моя мысль, что на начальных этапах разработки писать код так, чтобы в него легко вкатывались последующие изменения - бессмысленно.
потому что код получается наоборот избыточным, и сложным для модификации.
простейший пример неудобства инкапсуляции при расчете цены,
допустим у нас есть товары, которые в сумме стоят дешевле, чем по отдельности, т.е. , например, майка + футболка стоят дешевле, чем если их покупать по отдельности.
в данном случае, рассчитывать цену внутри объекта товара будет очень и очень тяжело, потому что придется туда тащить ссылку на родительскую коллекцию, соответственно сразу усложнится операции перемещение товара между коллекциями, клонирование, загрузка/выгрузка и т.д.
соответственно, особенно в бизнес-правилах, надо очень аккуратно инкапсулировать ту или иную информацию.

6yrop

как раз основные потребности рефакторинга две:
1. нам нужно внести изменения, но в существующий код эти изменения будут вноситься коряво
2. мы внесли изменения и нам перестал нравиться код
т.е. рефакторинг как раз и происходит либо до внесения нового изменения, либо после.
Все правильно, но... В начале мы написали код, и написали его так как нам нравится, в частности , чтобы его потом легко было читать. Теперь нам требуется внести добавления. На xslt это делается рефагторингом уже существующего кода, т.е. изменяем код, который нам нравится. На C# это делается без изменения существующего кода. Из чего я делаю вывод, что C# более удобный для этой цели язык, в нем не надо менять код, который нам нравится.
И еще, хотя рефакторинг автоматический, программист должен четко представлять, что произойдет с кодом, и он может ошибаться, упустить некоторые детали. Поэтому если в языке можно обойтись без рефакторинга, то этот язык лучше для данной ситуации.
Оставить комментарий
Имя или ник:
Комментарий: