Page 38 - Revista_60.pub
P. 38

A PROGRAMAR







        CLASSES DE INFRAESTRUTURA: A CLASSE USING

           Vejamos agora como construir a classe Using.         programador o trabalho de o instanciar, embora sofra altera-
                                                                ções na sua implementação para evitar duplicação de códi-
         type                                                   go. Vejamos então como ficam as suas implementações:
           Using = class
           public
             class procedure New                                class procedure Using.New<T>
               <T: class, constructor>                            (Obj: T; Action: TProc<T>);
               (Action: TProc<T>);                              begin
               static;                                            try
           end;                                                     Action(Obj);
                                                                  finally
                                                                    Obj.Free;
               A sua declaração é simples o bastante… Nada mais do     end;
         que  uma  classe  e  um  método  estático.  Este  irá  receber  por   end;
         parâmetro um método anónimo – que será a ação a executar
         sobre o objeto a instanciar - que por sua vez terá um parâme-  class procedure Using.New<T>
         tro genérico (que será obrigatoriamente uma classe – a classe     (Action: TProc<T>);
                                                                begin
         do  objeto  a  instanciar).  Vamos  então  ver  como  implementar     New<T>(T.Create, Action);
         este método:                                           end;
         class procedure Using.New<T>                                 O novo método é semelhante ao antigo, com a dife-
           (Action: TProc<T>);                                  rença de que não instancia o objeto. Simplesmente executa
         var                                                    a ação e liberta a memória no final. Já o método antigo pas-
           Obj: T;
         begin                                                  sa a usar o novo para cumprir o seu objetivo, passando-lhe
           Obj := T.Create;                                     por parâmetro o objeto já instanciado.
           try
             Action(Obj);                                             Assim, a classe Using tornou-se mais versátil, admi-
           finally                                              tindo ser usada com objetos cujo construtor necessite ou não
             Obj.Free;                                          de parâmetros.
           end;
         end;

               Este código parece familiar, não? É exatamente o mé-  Aumentando ainda mais a versatilidade da class Using:
         todo  2  mostrado  anteriormente.  Uma  variável  é  declarada,  a      É possível dar ainda mais versatilidade a esta classe,
         classe é instanciada, uma ação é executada com esse objeto,   se por exemplo permitirmos que esta retorne um parâmetro
         e a memória a ele alocada é no final liberta.          resultante da ação sobre o objeto.
               Na  sua  forma  mais  simples,  a  classe  Using  está  já
         completa. Uma classe de infraestrutura com um método estáti-  type
         co  que  permite  ter  uma  forma  diferente  de  gerir  o  tempo  de     Using = class
                                                                  public
         vida  de  um  objeto.  Claro  que  apresenta  algumas  limitações:       class procedure New
         Como  o  objeto  é  instanciado  pela  classe  Using,  e  esta  não         <T: class, constructor>
         tem como saber ao certo como o programador a quer instanci-        (Obj: T; Action: TProc<T>);
                                                                      overload; static;
         ar,  ela  assume  que  o  objeto  será  criado  com  recurso  a  um       class procedure New
         constructor sem parâmetros chamado Create.                   <T: class, constructor>
                                                                      (Action: TProc<T>);
               Vamos  então  ver  agora  como  deixar  a  classe  Using         overload; static;
         mais versátil, aceitando objetos previamente criados pelo pro-      class function New
         gramador, mas mantendo o restante funcionamento.             <T: class, constructor; TResult>
                                                                      (Obj: T; Action: TFunc<T>): TResult;
                                                                      overload; static;
         type                                                       class function New
           Using = class                                              <T: class, constructor; TResult>
           public                                                     (Action: TFunc<T>): TResult;
             class procedure New                                      overload; static;
               <T: class, constructor>                            end;
               (Obj: T; Action: TProc<T>);
               overload; static;                                      Os dois novos métodos são clones dos dois anterio-
             class procedure New
               <T: class, constructor>                          res,  apenas  usando  funções  no  lugar  de  procedimentos,  e
               (Action: TProc<T>);                              aceitando um segundo parâmetro genérico que será usado
               overload; static;                                como tipo de dados de retorno.
           end;
                                                                Esta seria a sua implementação:
               Acrescentámos, portanto, um novo método estático que
         permitirá receber por parâmetro o objeto já construído. O mé-  class function Using.New<T, TResult>
         todo  anterior  irá  ficar,  para  os  casos  onde  o  construtor  do     (Obj: T; Action: TFunc<T>): TResult;
         objeto  a  instanciar  não  tem  parâmetros,  poupando  assim  ao   begin
                                                                  try



                                                           38
   33   34   35   36   37   38   39   40   41   42   43