4D v16.3

Métodos de projeto

Página Inicial

 
4D v16.3
Métodos de projeto

Métodos de projeto  


 

 

Métodos de projeto são adequadamente nomeados. Considerando que o formulário e métodos do objeto estão vinculados aos formulários e objetos, um método de projeto está disponível em qualquer lugar, mas não é especificamente ligado a nenhum objeto particular do banco de dados. Um método de projeto pode ter uma das seguintes funções, dependendo de como ela é executada e usada:

  • Método de menu
  • Sub-rotina e função
  • Método de processo
  • Método de captura de evento
  • Método de captura de erro

Estes termos não fazem qualquer distinção entre métodos de projeto pelo que são, mas pelo que fazem.

Um método de menu é um método de projeto chamado a partir de um menu personalizado. Ele direciona o fluxo de sua aplicação. O método de menu toma o controle de ramificação, quando necessário, apresentando formulários, gerando relatórios e gerenciando sua base de dados em geral.

A sub-rotina é um método de projeto que pode ser pensado como um serviçal. Ele executa as tarefas que os outros métodos a solicitam para executar. Uma função é uma sub-rotina que retorna um valor para o método que a chamou.

Um método de processo é um método de projeto que é chamado quando um processo é iniciado. O processo dura apenas enquanto o método de processo continuar a executar. Para obter mais informações sobre os processos, consulte a seção de . Note-se que um método de menu anexado a um comando de menu cuja propriedade Iniciar um novo Processo é selecionado, é também o método de processo para o processo recém-iniciado.

Um evento de captura método é executado em um processo separado, como o método de processo de captura de eventos. Normalmente, você vai deixar 4D fazer tudo sobre a manipulação de eventos para você. Por exemplo, durante a entrada de dados, 4D detecta teclas e cliques, em seguida, chama o objeto correto e métodos de formulário que você possa responder adequadamente aos acontecimentos a partir de dentro destes métodos. In other circumstances, you may want to handle events directly. Por exemplo, se você executar uma operação demorada (como uma navegação de registros ), você pode querer ser capaz de interromper a operação, digitando Ctrl-Ponto (Windows) ou Cmd-Ponto (Macintosh). Neste caso, você deve usar um evento de captura método para fazer isso. Para obter mais informações, consulte a descrição do comando .

Um método de captura de erro é um método de projeto baseado em interrupções. Cada vez que um erro ou uma exceção ocorre, se executa no âmbito do processo em que foi instalado. Para obter mais informações, consulte a descrição do comando .

Um método de menu é chamado no ambiente de aplicativo quando você seleciona o comando de menu personalizado ao qual é anexado. Você atribui o método para o comando de menu usando o editor de Menu. O menu é executado quando o comando de menu é escolhido. Este processo é um dos principais aspectos da personalização de um banco de dados. Com a criação de menus personalizados com métodos de menu que executam ações específicas, você personaliza a sua base de dados. Consulte o manual de Design para obter mais informações sobre o editor de Menu.

Comandos de menu personalizados podem causar uma ou mais das atividades a ter lugar. Por exemplo, um comando de menu para a inserção de registros pode chamar um método que cumpre duas funções: exibir o formulário de entrada apropriado, e chamar o comando até o usuário cancelar a atividade de entrada de dados.

Automatizar seqüências de atividades é um recurso muito poderoso da linguagem de programação. Usando menus personalizados, você pode automatizar seqüências de tarefas e, portanto, fornecer mais orientações aos usuários do banco de dados.

Quando você cria um método de projeto, ele se torna parte da linguagem do banco de dados em que você cria. Você pode então chamar o método de projeto da mesma forma que vocês chama os comandos 4D built-in. Um método de projeto usado desta forma é chamado de sub-rotina.

Você pode usar sub-rotinas:

  • Reduzir codificação repetitiva
  • Esclarecer seus métodos
  • Facilitar alterações nos seus métodos
  • Modularizar seu código

Por exemplo, digamos que você tem uma base de dados de clientes. Como você personaliza o banco de dados, você acha que há algumas tarefas que você executa repetidamente, como encontrar um cliente e modificar o seu registo. O código para fazer isso pode ter esta aparência:

  ` Procurar um cliente
 QUERY BY EXAMPLE([Clientes])
  ` Selecione o formulário de entrada
 FORM SET INPUT([Clientes];"Entrada de dados")
  ` Modificar o registro do cliente
 MODIFY RECORD([Clientes])

Se você não usar sub-rotinas, você terá que escrever o código de cada vez que você deseja modificar um registro do cliente. Se há dez lugares no banco de dados personalizado, onde você precisa fazer isso, você terá que escrever o código dez vezes. Se você usar sub-rotinas, você só precisa escrever uma vez. Esta é a primeira vantagem de sub-rotinas - reduzir a quantidade de código.

Se o código descrito fosse um método chamado MODIFICAR CLIENTE, você poderia executá-lo simplesmente usando o nome do método em outro método. Por exemplo, para alterar o registro de um cliente e, em seguida, imprimir o registro, você deve escrever este método:

 MODIFICAR CLIENTE
 PRINT SELECTION([Clientes])

Esse recurso simplifica drasticamente seus métodos. No exemplo, você não precisa saber como o método MODIFICAR CLIENTE funciona, basta saber o que ele faz. Esta é a segunda razão para a utilização de sub-rotinas - esclarecer seus métodos. Desta forma, seus métodos tornam-se extensões para a linguagem 4D.

Se você precisa mudar o seu método de encontrar clientes neste banco de dados de exemplo, você vai precisar alterar um único método, não dez. Esta é a próxima razão para usar sub-rotinas - facilitar as mudanças de seus métodos.

Usando sub-rotinas, você torna o seu código modular. Isto significa simplesmente dividir o seu código em módulos (subrotinas), onde cada qual executa uma tarefa lógica. Considere o seguinte código de um banco de dados de conta corrente:

 BUSCAR CHEQUES EMITIDOS ` Encontre a cheques compensados
 CONCILIAR CONTA ` Conciliar a conta
 IMPRIMIR RELATÓRIOS DE CHEQUES ` Imprimir um relatório de cheques

Mesmo para quem não conhece o banco de dados, fica claro o que este código faz. Não é necessário analisar cada sub-rotina. Cada sub-rotina pode ter muitas linhas e realizar algumas operações complexas, mas aqui só é importante que ela execute sua tarefa.

Recomendamos que você divida o código em tarefas lógicas, ou módulos, sempre que possível.

Você encontrará frequentemente o que você precisa para passar dados para seus métodos. Isso é facilmente feito com parâmetros.

Os Parâmetros (ou argumentos) são peças de dados que um método precisa para executar sua tarefa. Os termos parâmetro e argumento são usados indistintamente ao longo deste manual. Parâmetros também são passados para comandos 4D. Neste exemplo, a string "Olá" é um argumento para o comando ALERT:

 ALERT("Olá")

Os parâmetros são passados para os métodos da mesma maneira. Por exemplo, se um método chamado FAZER ALGO aceita três parâmetros, uma chamada para o método pode ter esta aparência:

 FAZER ALGO(ComIsso;EAquilo;DesteModo)

Os parâmetros são separados por ponto e vírgula (;).

Na sub-rotina (o método que é chamado), o valor de cada parâmetro é automaticamente copiado para as variáveis locais numeradas seqüencialmente: $1, $2, $3, e assim por diante. A numeração das variáveis locais representa a ordem dos parâmetros.

As variáveis locais / parâmetros não são os campos reais, variáveis ou expressões passadas pelo método de chamada, pois eles contêm apenas os valores que foram passados.

Dentro da subrotina, você pode usar os parâmetros $1, $2 ... da mesma forma que você usaria qualquer outra variável local.

Nota: No entanto, no caso de você usar os comandos que modificam o valor da variável passada como parâmetro (por exemplo, Find in Field), os parâmetros $1, $2, e assim por diante, não pode ser usado diretamente. Primeiro, você deve copiá-los para o padrão de variáveis locais (por exemplo: $myvar: = $1).

Uma vez que eles são variáveis locais, eles estão disponíveis apenas dentro da sub-rotina e são limpos no final da sub-rotina. Por esta razão, uma sub-rotina não pode alterar o valor real dos campos ou variáveis passadas como parâmetros a nível método de chamada. Por exemplo:

  ` Aqui está um código do método MEU MÉTODO
  ` ...
 FAZER ALGO(Pessoas[Sobrenome]) `Digamos que Pessoas[Sobrenome] é igual a" Williams"
 ALERT(Pessoas[Sobrenome])
 
  `Aqui é o código do método FAZER ALGO
 $1:=Uppercase($1)
 ALERT($1)

A caixa de alerta exibida pelo método FAZER ALGO irá ler "Williams" ea caixa de alerta exibida pelo MEU MÉTODO irá ler "Williams". O método localmente alterou o valor do parâmetro $1, mas isso não afeta o valor do campo [Pessoas] Sobrenome passado como parâmetro pelo método MEU MÉTODO.

Existem duas maneiras de fazer o método FAZER ALGO alterar o valor do campo:

1. Ao invés de passar o campo para o método, você passa um ponteiro para ele, assim você poderia escrever:

  ` Aqui está um código do método MEU MÉTODO
  ` ...
 FAZER ALGO(->[Pessoas]Sobrenome) `Digamos que [Pessoas] Sobrenome é igual a "Williams"
 ALERT(Pessoas[Sobrenome]) `Aqui está o código do método FAZER ALGO
 $1->:=Uppercase($1->)
 ALERT($1->)

Aqui, o parâmetro não é o campo, mas um ponteiro para ele. Portanto, dentro do método FAZER ALGO, $ 1 não é mais o valor do campo, mas um ponteiro para o campo. O objeto referenciado por $1 ($1 -> no código acima) é o campo em questão. Por conseguinte, alterar o objeto referenciado ultrapassa o âmbito da sub-rotina, e no campo real é afetada. Neste exemplo, ambas as caixas de alerta irão ler "Williams".

Para mais informações sobre ponteiros, consulte a seção .

2. Ao invés de ter o método FAZER ALGO "fazendo algo", você pode reescrever o método para que retorne um valor. Assim, você poderia escrever:

  ` Aqui está um código do método MEU MÉTODO
  ` ...
 [Pessoas] Sobrenome:=FAZER ALGO([Pessoas] Sobrenome)'Digamos que[Pessoas] Sobrenome é igual a" Williams"
 ALERT(Pessoas[Sobrenome])
  ` Aqui está o código do método FAZER ALGO
 $0:=Uppercase($1)
 ALERT($0)

Esta segunda técnica de retornar um valor através de uma sub-rotina é chamada "usando uma função." Isso é descrito nos próximos parágrafos.

Nota avançada: Os parâmetros dentro da sub-rotina são acessíveis através de variáveis locais $ 1, $ 2 ... Além disso, os parâmetros podem ser opcionais e podem ser consultados usando a sintaxe ${...}. Para mais informações sobre parâmetros, consulte a descrição dos parâmetros do comando Count parameters.

Quando usar campos, valores e expressões de tipo escalar como parâmetros de método, apenas cópias de valores são passadas.

Jà que $1, $2... são variáveis locais, elas estão disponíveis apenas dentro da subrotina e são apagados ao final da subrotina. Por isso, uma subrotina não pode mudar o valor atual dos campos ou variáveis passados como parâmetros ao nível de chamada de método. Por exemplo:

  ` Código do método MY METHOD
  ` ...
 DO SOMETHING([People]Last Name) ` Por exemplo [People]Last Name é igual a "williams"
 ALERT([People]Last Name)
 
  ` Código do método DO SOMETHING
 $1:=Uppercase($1)
 ALERT($1)

A caixa de diálogo exibida por  DO SOMETHING lerá  “WILLIAMS” e a caixa de alerta exibida por  MY METHOD vai ler “williams”. O método mudou localmente o valor do parâmetro $1, mas isso não afetou o valor do campo [People]Last Name passado como parâmetro pelo método MY METHOD.

Há duas maneiras de fazer com que o método DO SOMETHING mude o valor do campo:

1. Ao invés de passar o campo ao método, passe um ponteiro, portanto escrevendo:

  ` Código do método MY METHOD
  ` ...
 DO SOMETHING(->[People]Last Name) ` Se [People]Last Name for igual a "williams"
 ALERT([People]Last Name)
 
  ` Código do método DO SOMETHING
 $1->:=Uppercase($1->)
 ALERT($1->)

Aqui o parâmetro não é o campo, mas o ponteiro ao campo. Portanto, dentro do método DO SOMETHING , $1 já não é o valor do campo, mas um ponteiro ao campo. O objeto referenced por $1 ($1-> no código acima) é o campo real. Por isso, mudar o objeto referenciado vai além do escopo da subrotina, e o campo verdadeiro é afetado. Neste exemplo, ambas as caixas de alerta lerão “WILLIAMS”.

Para saber mais sobre Ponteiros, ver Ponteiros.

2. Ao invés de ter o método DO SOMETHING “fazendo algo,” pode reescrever o método de modo que retorne um valor. Pode escrever:

  ` Código do método MY METHOD
  ` ...
 [People]Last Name:=DO SOMETHING([People]Last Name) ` Se [People]Last Name for igual a "williams"
 ALERT([People]Last Name)
  ` Código do método DO SOMETHING
 $0:=Uppercase($1)
 ALERT($0)

Essa segunda técnica de retornar um valor por uma subrotina é chamado "usar uma função". Isso é descrito nos próximos parágrafos.

Quando usar variáveis, expressões ou campos do tipo objeto ou coleção como parâmetro de métodos, referências aos valores atuais da fonte são passadas. Neste caso, $1, $2...não contém valores, mas referências. Modificar os valores dos parâmetros  $1, $2... dentro da subrotina fará com que sejam propagados onde quer que o objeto ou coleção da fonte seja usado. Este é o mesmo princípio que o dos ponteiros, exceto que os parâmetros  $1, $2... não precisam ser de-referenciados na subrotina.

Por exemplo:

  //O méotod CreatePerson cria um objeto e o envia como um parâmetro
 C_OBJECT($person)
 $person:=New object("Name";"Smith";"Age";40)
 ChangeAge($person)
 ALERT(String(OB get($person;"Age")))

  //O método ChangeAge adiciona 10 ao atributo Age (idade) do objeto recebido
 C_OBJECT($1)
 OB SET($1;"Age";OB Get($1;"Age")+10)
 ALERT(String(OB get($1;"Age")))

Se executar o método CreatePerson as duas caixas de alerta vão ler  "50" já que a mesma referência é gerenciada por ambos os métodos

4D Server: Quando parâmetros são passados entre métodos que não são executados na mesma máquina (usando por exemplo a opção Execute on Server, ver Definir as propriedades dos métodos de projeto), as referências não são usáveis. Nesses casos, cópias de parâmetros objeto e coleções são enviadas ao invés de referências.

Os dados podem ser retornados de métodos. Um método que retorna um valor é chamad de função.

Comandos 4D ou comandos de Plug-in 4D que retornam um valor também são chamados de funções.

Por exemplo, a linha a seguir é uma declaração que usa a função interna, Length, para retornar o comprimento de uma string. A instrução atribui o valor retornado em uma variável chamada MeuComprimento. Aqui está a instrução

 MeuComprimento:=Length("Como eu vim parar aqui?")

Qualquer sub-rotina pode retornar um valor. O valor a ser devolvido é colocado na variável local $0.

Por exemplo, a função seguinte, chamado Maiúsculas4, retorna uma string com os quatro primeiros caracteres da string passada para ela em letras maiúsculas:

 $0:=Uppercase(Substring($1;1;4))+Substring($1;5)

A seguir um exemplo que usa a função Maiúsculas4 :

 NuevaFrase:=Maiúsculas4("Isto é bom.")

Neste exemplo, a variável recebe NovaFrase "ISTO é bom.”

O resultado da função, $0, é uma variável local dentro da sub-rotina. Ele pode ser usado como tal, com a sub-rotina. Por exemplo, no exemplo anterior FAZER ALGO $0 foi atribuído ao valor de $1, então usado como parâmetro para o comando ALERT. Dentro da sub-rotina, é possível usar $0, da mesma forma que você usaria qualquer outra variável local. É 4D que retorna o valor de $0 (quando termina a sub-rotina) para o método chamado.

Métodos de projeto podem chamar a si mesmo. Por exemplo:

  • O método A pode chamar o método B, que poderá chamar então A, que irá chamar B novamente e assim por diante.
  • Um método pode chamar a si mesmo.

Isso é chamado de recursão. A linguagem 4D apoia plenamente a recursividade.

Aqui está um exemplo. Digamos que você tem uma tabela [Amigos e Parentes], composta por este conjunto de campos extremamente simplificado:
- [Amigos e Parentes]Nome
- [Amigos e Parentes]NomeFilho

Para este exemplo, nós assumimos que os valores nos campos são únicos (não existem duas pessoas com o mesmo nome). Dado um nome, você quer construir a frase "Um amigo meu, John, que é o filho de Paul, que é o filho de Jane, que é o filho de Robert, que é o filho de Leonor, faz isso para viver!":

1. Você pode construir a frase da seguinte maneira:

 $vsNome:=Request("Digite o nome:";"Juan")
 If(OK=1)
    QUERY([Amigos e Parentes];[Amigos e Parentes]Nome=$vsNome)
    If(Records in selection([Amigos e Parentes])>0)
       $vtTodalahistoria:="Um amigo meu, "+$vsNome
       Repeat
          QUERY([Amigos e Parentes];[Amigos e Parentes]NinosNome=$vsNome)
          $vlQueryResult:=Records in selection([Amigos e Parentes])
          If($vlQueryResult>0)
             $vtTodahistoria:=$vtTodahistoria+", que é filho de"+[Amigos e Parentes]Nome
             $vsNome:=[Amigos e Parentes]Nome
          End if
       Until($vlQueryResult=0)
       $vtTodahistoria:=$vtTodahistoria+", faz isto para viver!"
       ALERT($vtTodahistoria)
    End if
 End if

2. Você também pode construí-lo desta maneira:

 $vsNome:=Request("Digite o nome:";"Juan")
 If(OK=1)
    QUERY([Amigos e Parentes];[Amigos e Parentes]Nome=$vsNome)
    If(Records in selection([Amigos e Parentes])>0)
       ALERT("Um amigo meu, "+Genealogia de($vsNome)+", faz isto viver!")
    End if
 End if

Com a função recursiva Genealogia de listada aqui:

  ` Método de projeto Genealogia de
  ` Genealogia de ( String ) -> Texto
  ` Genealogia de ( Nome ) -> Parte da frase
 
 $0:=$1
 QUERY([Amigos e Parentes];[Amigos e Parentes]NomeFilho=$1)
 If(Records in selection([Amigos e Parentes])>0)
    $0:=$0+" filho de "+Genealogia de([Amigos e Parentes]Nome)
 End if

Note que o método Genealogia de chama a si mesmo.

A primeira forma é um algoritmo iterativo. A segunda maneira é um algoritmo recursivo.

Ao implementar o código para casos como o do exemplo anterior, é importante notar que você sempre pode escrever por meio de métodos de iteração ou recursão. Normalmente, recursão fornece um código de manutenção mais conciso e legível, mas o uso não é obrigatório.

Alguns usos típicos de recursão em 4D são:

  • Tratar registros em tabelas que se relacionam entre si da mesma forma como no exemplo.
  • Navegar em documentos e pastas em seu disco, usando os comandos e . A pasta pode conter pastas e documentos, as subpastas pode conter pastas e documentos, e assim por diante.

Importante: as chamadas recursivas devem terminar sempre em algum ponto. No exemplo, o método de Genealogia pára de chanar a si mesmo quando a consulta não retorna registros. Sem essa condição de teste, o método poderia chamar-se indefinidamente, eventualmente, 4D retornaria um erro de "pilha completa", porque não teria mais espaço para "acumular" as chamadas (bem como os parâmetros e variáveis locais utilizados na fórmula).



Ver também 

Controle de fluxo
Métodos
Métodos de banco de dados

 
PROPRIEDADES 

Produto: 4D
Tema: Apresentação da linguagem

 
HISTÓRIA 

 
ARTICLE USAGE

Manual de linguagem 4D ( 4D v16)
Manual de linguagem 4D ( 4D v16.1)
Manual de linguagem 4D ( 4D v16.2)
Manual de linguagem 4D ( 4D v16.3)