A Cozinha da Composição
Boas novas. Acaba de sair o Composite Application Guidance para WPF. Além de exemplos e código fonte que mostram como compor uma interface gráfica, ele contém também uma referência interessante aos patterns utilizados em https://msdn.microsoft.com/en-us/library/cc707841.aspx. Vale uma olhada.
Composição é umas das técnicas mais importantes da computação e tem ganhado novas armas nestas últimas décadas. Começamos com a composição de estruturas de dados e de funções (funções chamando funções) e hoje chegamos à composição de objetos, componentes, classes genéricas, módulos, etc.
Nos 90, meu sonho era instanciar meu site com comandos como new Site<Session<SQLSession>, Security<Https, Token>, ProcessModel<OutProcess>>. Hoje podemos fazer isto de forma elegante e dinâmica usando frameworks para injeção de dependência como o Unity Application Block.
A composição de funções é uma que por vezes é esquecida, mas que vale a pena ser revisitada. Um exemplo: esta semana estava precisando calcular um produto do quadrado dos valores de um array e logo me lembrei do Linq. Não sou expert em Linq e consegui realizar o produto com dois loops invisíveis. Veja o código:
double [] l = { 1, 2, 3 };
IEnumerable<double> ld = from o in l select o*o;
double result = ld.Aggregate<double>((x,y)=>x*y);
Insatisfeito com o duplo loop, parti para implementar uma função que recebe como argumentos o tipo da agregação e a operação para cada elemento do array. Aqui está a função:
public class math
{
public delegate double f(double x);
public delegate double oper(double x, double y);
static public double fromto( IEnumerable<double> l,
oper aggregate_op, f func )
{
double result = func(l.First<double>());
foreach (double d in l.Skip<double>(1))
{
result = aggregate_op(result, func(d));
}
return result;
}
}
Veja como ficou simples utilizá-la:
double [] l = { 1, 2, 3 };
result = math.fromto(l, (x,y)=>x*y, y=>y*y );
Meu ponto: composição é como o molho de um bom design. Usado com simplicidade e elegância pode dar valor renovado ao seu prato principal.