domingo, 29 de junho de 2008

Convenções e Padrões - Java

Observo no cenário de IT, de forma generalizada, um comportamento comum, um “modus operandi” dos fornecedores de tecnologia: Todos prometem ganho de produtividade, robustez, escalabilidade, interoperabilidade e etc. como se essas features fossem exclusivamente elementos pertinentes aos seus domínios. Sendo somente eles conhecedores, tanto do “por que”, quanto da solução, do problema. Além do fato que, obviamente, antes deles ninguém jamais mencionou nada a respeito. Enquanto isso ... em “Gotham City”, (na vida real, na prática,) quase tudo que um promete, jurando exclusividade, é exatamente a mesma coisa que o outro garante só ele oferecer ao mercado. Hehhheeh ... seria até engraçado se não fosse trágico.
O que não é nada legal nesse cenário, é a parte que nos cabe. Os consumidores dessas tecnologias, analistas e desenvolvedores, nós que sempre ficamos com a impressão de que compramos meio quilo de Manjuba a preço de Haddock. Acho que posso melhorar a metáfora: A propaganda nos faz sonhar com Badejo, logo pedimos dois quilos. Contudo, o produto que recebemos é Manjuba, meio quilo, pelo qual pagamos preço de Haddock.

Por exemplo, nos atendo somente ao que tange a conceitos (abstraindo as questões financeiras implicadas): Figura comum certo estereótipo “tech-evangelistas”, pregam a orientação a objetos com tal ortodoxia que quase chegam a convencer que eles são os únicos no mundo que possuem o mérito de ousar falar sobre o assunto sagrado. Eles apresentam então, um mito de proporções colossais, mistério revelado somente aos sacerdotes iniciados por decorrência de uma eleição divina. Divindade essa que só eles conhecem, suponho ... hehehehee!!!
Tudo bem, vou desconsiderar, neste momento, se o conteúdo das pregações é aderente ou não. Suponha que não seja relevante se alguém aprende OO. Muito ou pouco, não importa agora. O que eu acho intrigante é que toda “hermenêutica” desses pseudo-pregadores (normalmente de tecnologias que estão na moda) não difere uma vírgula, no que diz respeito ao cerne do conceito, da abordagem a orientação a objetos por outras tantas tecnologias. Entretanto, apesar disso, muitos deles exalam aquele tom ex-cathedra quando o assunto está em pauta. Conseqüentemente, contrastam pateticamente com o que intencionam esforçadamente aparentar. O pior de tudo é que acabam sendo aceitos como referência por muitos outros profissionais. Lamentável ....
Para finalizar o “momento desabafo”, quando o assunto é padronização e convenções, semelhantemente acontece a mesma coisa. Cada um fala de padrões como se fossem os únicos a terem consciência da relevância da adoção dos mesmos.

Uma pesquisa divulgada pela Sun alerta que ao longo da vida útil de um sistema, 20% do esforço será despendido na criação e no teste do código original. Ao passo que, 80% do esforço será despendido posteriormente na manutenção e em melhorias subseqüentes que sofrerá o software. Visto isso, (em primeiro lugar vamos fingir que somente a Sun detectou esse fenômeno, portanto prossigamos ...) é imperativo considerar que programar usando um conjunto de padrões ajuda a diminuir o esforço envolvido em testar, fazer a manutenção e melhorar qualquer código. Por isso, a Sun criou um conjunto de padrões de programação para Java, e publicou esses padrões num documento inteligentemente chamado de "Convenções de Código ]ava", que você pode encontrar em java.sun.com. É um documento, curto e fácil de ler, que recomendamos enfaticamente.

OBS: Obviamente essa questão de padronização é relevante para qualquer outra linguagem de programação. Por exemplo, no caso do Delphi, a Borland (fabricante original da ferramenta) padronizou e recomenda um padronização para codificação de um programa em Delphi.

Classes e Interfaces: A Primeira letra deve ser maiúscula. No caso de nomes que sejam palavras compostas, a primeira letra de cada palavra deve ser maiúscula.
No caso de classes o nome deve ser sempre um substantivo. Exemplo:

EstacaoZnDummyClasse
AutomovelEsportivo
Automovel

No caso de Interfaces o nome deve ser adjetivos. Exemplo:

Runnable
Serializable


Métodos: A primeira letra sempre em caixa baixa. No caso de palavras compostas, a primeira letra sempre em caixa baixa, as demais palavras seguintes iniciam por letra maiúscula. Além disso, os nomes dos métodos devem sempre ser uma composição par de palavras: a primeira um verbo, seguindo de um substantivo. Exemplo: “playSong();”, “getName()”.

Variáveis: quanto a caixa, segue a mesma lógica que os métodos. Inicia com letra minúscula. No caso de palavras compostas, a primeira letra sempre em caixa baixa, as demais palavras seguintes iniciam por letra maiúscula. Não devemos usar verbo para nomear variável. Exemplo: largura (width), cor (color), nome (name).

Constantes: As constantes Java são criadas marcando-se variáveis como estáticas e finais. Elas devem ser nomeadas usando-se letras maiúsculas com caracteres underscore como separadores. Exemplo: “INDICE_ECONOMICO”, “A_NAME_PATH_PRG”.

Padrões JavaBeans

No momento só estou preocupado em conhecer a especificação.

No livro da Kathy Sierra, ela refere-se a especificação JavaBeans como uma padronização para reuso de componentes, vejamos:
Os ambientes integrados de desenvolvimento, chamados por IDE, objetivam facilitar o desenvolvimento de softwares. Provendo maior produtividade e gerenciamento dos projetos. A especificação JavaBeans criada para ser um padrão para o desenvolvimento de componentes, os quais possam ser facilmente usados por outros desenvolvedores numa IDE. Seja para o NetBeans ou para o Eclipse, é possível adquirir componentes de terceiros que facilitem a implementação do seu projeto. Usar regras de nomeação JavaBeans é a forma de garantir que outras ferramentas poderão reconhecer e usar componentes cridos por desenvolvedores distintos. O conhecimento da API JavaBeans é fundamental para o exame de certificação.

Encontrei uma definição na web que define: Javabean é um componente de software reusável, normalmente usado em aplicações standalone e applets. Descando como principais característas: Instrospecção, customização, eventos, propriedades e persistência.

Vejamos o que a Kathy fala sobre propriedades:
Propriedades são variáveis de instância privadas. Portanto a única forma de comunicação entre elas e o mundo exterior é através de métodos públicos que funcionem como uma interface entre essas variáveis e o mundo externo a classe. Logo, a especificação JavaBean precisa de dois métodos para permitir acesso as propriedades da classe: Um para atribuir valor e outro para recuperar valor. O método cujo a função é permitir atribuição de valor para a variável privada é chamado de “setter”. Enquanto que o método que permite recuperar o valor de uma propriedade é chamado de getter.

Regras para nomeação de propriedades JavaBean que são argüidas no exame de certificação (segundo o livro da Kathy Sierra):

O Prefixo para qualquer método getter deve ser “get”, exceto no caso de propriedades cujo o tipo é booleano. Neste caso é permitido tanto “get” como prefixo, como também “is”. Exemplo:

getNomeCliente();
getTituloComposicao();
getTotalVenda();
IsPlaying() ou getPlaying(); // propriedade booleana.
IsEmpty();// propriedade booleana.


Para qualquer método “setter” (atribuidor de valor), o prefixo deve ser “set”. Exemplo:

setNomeCliente(String Nome);
setTituloComposicao(String Composicao);
setPrecoCompra(Double Valor);


Para compor o nome de um método, “getter” ou “setter”, completo, passe a primeira letra do nome da propriedade para maiúscula em seguida adicione o prefixo apropriado (“get”, “is” ou “set”).

As assinaturas de métodos “setter” devem ser marcadas como públicas, o tipo de retorno é sempre “void”. Além disso um argumento que represente a propriedade (do mesmo tipo da propriedade).


As assinaturas de métodos “getter” devem ser marcadas como públicas. Não existem argumentos. Todavia, devem ter um tipo de retorno compatível com a propriedade em a qual ele se propõe recuperar o valor.

Suporte a Eventos:
A especificação JavaBean se propõe a suportar eventos. Desta forma permitindo aos componentes notificarem uns aos outros quando algo acontece. Semelhante ao conceito extensivamente conhecido pelos programadores Delphi desde a versão um da ferramenta, o modelo de eventos JavaBeans freqüentemente é usado em aplicações GUI. Por exemplo, quando um evento qualquer, como um clique do mouse, é comunicado para muitos outros objetos, esses outros objetos podem executar ações quando isso ocorrer (Oh!!! hehehe). Os objetos que recebem a informação de que ocorreu um dado evento são chamados de listeners. Para o exame, você precisa saber que os métodos que são usados para adicionar ou remover listeners de um evento devem também seguir padrões de nomeação JavaBean:


Regras de Nomeação de Listeners JavaBean:

Os nomes de métodos listeners usados para "registrar" um listener como uma fonte de eventos devem usar o prefixo “add”, seguido do tipo do listener. Por exemplo: addActionListener ().

Nomes de métodos listeners usados para "desregistrar", ou seja remover, um listener devem usar o prefixo “remove”, seguido do tipo do listener (usando-se as mesmas regras que o método add de registro).

O tipo de listener a ser adicionado ou removido deve ser passado como o argumento para o método.

A seguir, exemplos de assinaturas de métodos JavaBean válidas:


// método setter
public void setValueZn(int value);

//método getter
public int getValueZn();

// Métodp getter
public boolean isZnUpdated();

// Removendo o listener
public void removeMyListener(MyListener m)

// Adicionando um listener para dar a classe suporte a eventos
public void addZnListener(ZnListener AZn)


Exemplificando de assinaturas de métodos JavaBean inválidos:

void setCustomerZn (String sZn); // Ausência da palavra reservada “public”


Um método setter tem que ser declarado como público


public void modifyZnValue(int vZn); // Uso da palavra reservada modify não
é permitido

public void addYnxListener(ZnListener xZn); //Tipo do listener incompatível

public void getZnPostNUmber(int znNumber); // um método getter que não retorna
nada e possui argumento.


Artigo completo (View Full Post)

Revisão sobre Java II

No artigo anterior, sobre Java, um dos pontos que tocamos em nossa revisão sobre Java foi sobre as palavras reservadas. Segue uma listagem dessas palavras.

Lista das palavras reservadas em Java:

abstract, assert,
boolean, break, byte,
case, catch, char, class, const, continue,
default, do, Double, else,
enum, extends,
final, finally, float, for,
goto //(cruz credo!),
if, implements, import, instanceof, int, interface,
long,
native, new,
package, private, protected, public,
return,
short, static, strinctfp, super, switch, synchronized,
this, throw, throws, transient, try,
void, volatile,
while


Dando continuidade ao assunto vejamos agora sobre como adicionar comentários em seus programas Java:

Comentário num programa Java:

O Java absorveu os delimitadores de comentários das linguagens C e C++:

1) “/* */” Comentário de múltiplas linhas, vem do C.
2) “//” Comentário de uma linha, vem do C++
3) “/** */” Comentário de documentação (javadoc)

O delimitador mais usado é o padrão “//” de uma linha, do C++.

Ok, até aqui tudo tranqüilo! Vamos criar um pequeno exemplo para ilustrar o que vimos no artigo anterior, além de exemplificarmos os delimitadores de comentário. Adiante comentaremos cada linha do programa, seguindo o estilo Deitel & Deitel.

// A linha abaixo especifica que a classe esta definida no pacote "ZNDummyPkg"
package ZNDummyPkg;

import javax.swing.JOptionPane;
/** comentário varias linhas JDoc... bla bla bla!!!
* @author GMottaZn
*/
public class ZNDummyClasse {

public static void main(String[] args) {
JOptionPane.showMessageDialog(null, " Estação Zn!!! Codificando minha classe Java");
}

}



Detalhando o programa ZNDummy

Lina 1 – Exemplificando comentário de uma linha.
Uma ação bastante desprezada por muitos programadores, colocar comentário nos seus programas melhora o entendimento do módulo codificado, alem de ser uma forma otimizada de documentar o sistema.

Linha 2 - Especifica que a classe esta definida no pacote "ZNDummyPkg". Como estou usando o NetBeans para construir meus exemplos ele cria uma package para definição de classes.

Linha 3 – Simplesmente uma linha em branco. O uso de linhas em branco pode ajudar a melhorar a legibilidade do seu código. A tabulação também funciona na mesma idéia. É claro que é algo para ser usado meticulosamente (cuidadosamente, com prudência). Acredito que em linguagens que não obrigam seçoes, ou áreas, de declarações como o Pascal, o uso desse recurso é mais necessário.

Linha 4 - Importando pacote de extensão da Java API.

Linha 5, 6 e 7 - Comentário de múltiplas linhas para documentação Javadoc.

Linha 8 - Iniciamos a declaração de uma classe em Java. A classe ZNDummyClass. Ilustrando o que foi falado no artigo anterior sobre um programa em Java, veja que a palavra reservada “class” indica a declaração de uma classe. A palavra reservada “class” deve vir seguida imediatamente do identificador, o qual dará nome a classe. Em muitos livros sobre Java, você poderá encontrar o termo “palavras chaves” referindo-se as palavras reservadas. As palavras reservadas devem sempre ser digitadas em caixa baixa, lembre-se o Java é sensível a caixa.
Convencionalmente todos os identificadores de classes devem começar por letra maiúscula. Ou seja, os nomes das classes devem iniciar com letra maiúscula. Antes da palavra reservada “class” existe outra palavra reservada, “public”. Ela define a visibilidade dessa classe em relação a um pacote (package). Por exemplo, quando você define uma classe como não pública, o escopo de visibilidade dela fica restrito somente a package onde ela está definida. Isso significa que ela só poderá ser chamada e usada pelas classes que estejam na mesma package que ela.
Conforme mencionei anteriormente, é possível, e freqüentemente é o que fazemos, usar bibliotecas de classes preexistentes, como a Java API por exemplo. Cada classe ou interface na Java API pertencem a um pacote específico. Organizar seus programas em pacotes pode ajudá-lo a administrar a complexidade de cada componente existente nele. Além de facilitar a reutilização, reuso, dos componentes de software, de maneira que possam ser importados por outros programas. Quando iniciamos um novo projeto no NetBeans automaticamente ele cria uma package associada a este projeto.

Linha 9 – Espaço em branco cujo objetivo é alcançar boa legibilidade do código.

Linha 10 – “public static void main (String args[])”:
Os programas Java começam a execução pelo método principal, é o "main". Os parênteses que vimos depois da palavra reservada “main” indicam que esse é um bloco de construção de programa o qual chamamos método (Falamos extensivamente sobre métodos aqui no ZN, tanto em Delphi, C#, PHP,quanto em Java). Definições de classe tanto em Java, quanto nas demais linguagens, normalmente, devem possuir, pelo menos um, ou, preferivelmente, mais métodos. Em Java, numa definição de classe justamente um desses métodos deverá ser chamado de “main” e definido conforme a linha 5 do nosso exemplo. De outra forma o interpretador Java não executará o programa, ou aplicativo ... que seja. A palavra reservada “void” indica que esse método não retorna nada. Nenhum tipo de dado, nenhuma informação. Em Java, como em C, não existe o conceito de “procedure” como no Pascal. Só existe function, quando não é conveniente definir um retorno para esse function definimos ela como “void”. A procedure, em Delphi, por exemplo, é como se fosse uma function que não retorna nada.

Linha 11 - O símbolo “{” inicia o corpo da implementação do método cujo o correspondente “}” , na linha 13, é o delimitador que define o final do método principal. As chaves são os delimitadores de blocos de comando, assim como em Pascal usamos o “begin” e o “end”.

Linha 12 – Fazendo chamada ao método, de uma classe da Java API, “showMessageDialog”. O qual é responsável por ser o out put da minha mensagem.

Linha 13 – Delimitador final do método principal da classe ZNDummyClasse.

Linha 14 - Espaço em branco cujo objetivo é alcançar boa legibilidade do código.

Linha 15 – Delimitador final da definição da classe ZNDummyClasse.

Veremos mais posteriormente ...

Artigo completo (View Full Post)

sábado, 28 de junho de 2008

BDS 2006 & Javascript - Intraweb 8.0

O Intraweb ainda continua presente nas versões mais recentes o Delphi. Ao que parece, a versão do framework que acompanha o no BDS 2006 apresenta alguma novidade. Contudo, muita coisa importante parece não ter mudado. Por exemplo, o fonte dos componentes ainda não é acessível aos desenvolvedores. Confesso que vejo com grande antipatia essa característica proprietária da Atozed. Postura incompatível com a demonstrada por grandes fornecedores de tecnologias que se destacam atualmente. Isso me remete ao sentimento de que ao usar um produto da Atozed o desenvolvedor está lhe dando com uma empresa cujo a mentalidade reflete uma postura feudal, própria da miserável e subdesenvolvida América latina.
Pretendo criar alguns exemplos (nandjares de mirolands) para experimentar como se comporta o Intraweb 8.0.1, que esta presente no DBS 2006. (Veja: Intraweb e Delphi 7)


Iniciando nosso primeiro exemplo

No BDS 2006, para iniciar um novo projeto selecione no menu: File ► New ► Other. Em
seguida, selecione no diálogo seguinte (caixa de dialogo) IntraWeb Application Wizard. A partir da Treeview (Item Categories) conforme ilustrado na figura abaixo:





No diálogo seguinte definiremos algumas configurações importantes para nossa aplicação web.



StandAlone Application: Essa opção permite desenvolver o aplicativo Intraweb sem a necessidade de deploy em servidor web (IIS por exemplo). Isso traz algum conforto, visto que, assim é dispensável configurações obrigatórias para desenvolvimento que exija deploy e sincronismo com o servidor. Outra vantagem é que essa opção oferece um recurso de “Debug” idêntico o experimentado pelo desenvolvedor quando trabalha na IDE do Delphi com aplicações desk top. A partir dessa configuração seu aplicativo Intraweb, quando o F9 é pressionado, é “executado” pelo Browser, contudo para debuggar basta marcar o brack point (F5) na linha desejada e prosseguir como se você estivesse desenvolvendo um aplicativo convencional.
Pool Data Connection: Como o próprio título indica, refere-se a pool de conexões. Bem, tenho que confiar no que está indicando essa propriedade pois no momento não tenho como testar quase nada sobre ela.
Create User Session: Cria uma declaração, automaticamente, no seu novo projeto, de um obejto da classe TUserSession. Esse objeto, também conhecido desde a versão 5.0, tem o objetivo de ser um gerenciador de seção.
Durante muito tempo o gerenciamento de seção sempre foi uma parte sensível, bastante trabalhosa, nos primórdios do desenvolvimento para web. Na época do Delphi 7, esta estratégia de gerenciamento de seção foi uma feature que fez o Intraweb dar coro em nas tecnologias web vigentes naquela época.
Project Name: Define o nome do projeto.

Project Directory: O Framework Intraweb tem a particularidade de solicitar o path do diretório onde ficará o projeto. No contexto web isso tem uma particular importância por causa de obrigatoriedade da dependência de um servidor web. Porque ele é responsável pela interpretação e disponibilização do seu programa em forma de serviço web. Você pode estar se perguntando: “Ora, definimos o exemplo como ‘Stand Alone Application’, logo não tem servidor web. Correto?”. Errado meu caro, o Intraweb no módulo Stand Alone Application possui uma funcionalidade que simula um servidor web. O simples fato desse detalhe ficar transparente para o desenvolvedor não é a prova de que não exista a necessidade do servidor web.
Outra coisa sobre “Project Directory” ele não usa a API do windows para selecionar um diretório, isso é tosco. Em compensação, você pode digitar um diretório que não exista ainda, ele cria pra você.

Main Form: Define se o aplicativo suportará tecnologia para dispositivos móveis

De cara já percebemos novidades, pretendo verificar até que ponto elas nos representarão vantagem efetivas ou não.

Após essas configurações iniciais, click no botão “OK” e o BDS vai criar pra você as seguintes Units:




Unit1: Este é o formulário Intraweb principal do seu projeto. Esta está nomeado de “IWForm1”.

DatamoduleUnit: Como o próprio nome indica, trata-se do Datamodule (TDatamodule).

unit DataModuleUnit;

interface

uses
{$IFDEF Linux}QForms, {$ELSE}Forms, {$ENDIF}
SysUtils, Classes;

type
TDataModule1 = class(TDataModule)
private
public
end;


implementation

{$R *.dfm}

end.

ServerController: Onde está definido a classe que faz a interface com o servidor web. TIWServerController (IWServerController). Esta classe é também onde definimos muitas propriedades importantes do aplicativo web que estamos construindo.




UserSessionUnit: Gerenciador de seções do Intraweb. Nas versões anteriores, o UserSession era uma classe definida na unit do ServerController.Veja um exemplo de uma Unit “ServerController” do Delphi 7 (Intraweb 5.0):

unit ServerController;
{PUBDIST}

interface

uses
Classes,
UDm,
IWServerControllerBase, IWAppForm, IWApplication,
SysUtils;

type
TIWServerController = class(TIWServerControllerBase)
procedure IWServerControllerBaseNewSession(ASession: TIWApplication;
var VMainForm: TIWAppForm);
private
public
end;

// This is a class which you can add variables to that are specific to the user. Add variables
// to this class instead of creating global variables. This object can references by using:
// UserSession
// So if a variable named UserName of type string is added, it can be referenced by using:
// UserSession.UserName
// Such variables are similar to globals in a normal application, however these variables are
// specific to each user.
//
// See the IntraWeb Manual for more details.
TUserSession = class(TComponent)
public
FrmDm: TFrmDm;
//
constructor Create(AOwner: TComponent); override;
end;

// Procs
function UserSession: TUserSession;

implementation
{$R *.dfm}

uses
IWInit;

function UserSession: TUserSession;
begin
Result := TUserSession(RWebApplication.Data);
end;

{ TUserSession }

constructor TUserSession.Create(AOwner: TComponent);
begin
inherited;
FrmDm := TFrmDm.Create(AOwner);
end;

procedure TIWServerController.IWServerControllerBaseNewSession(
ASession: TIWApplication; var VMainForm: TIWAppForm);
begin
ASession.Data := TUserSession.Create(ASession);
end;

end.

Dando uma olhada rápida nessas units em termos de arquitetura o Intraweb mudou um pouco a organização entre as classes TServerController e TUserSession, porém ainda continua trabalhando com serialização de objetos. Veja que neste trecho de código do ServerController as classes são acessadas não por uma variável mas por uma função:


function UserSession: TIWUserSession;
function IWServerController: TIWServerController;
function LockDataModule: TDataModule1;
procedure UnlockDataModule(ADataModule: TDataModule1);


Observamos também que TUserSession agora herda de “TIWUserSessionBase”. Mas isso nos deixa muito pouca informação porque não temos acesso a definição desse ancestral.
Javascript no Intraweb 8.0.1
Pretendo testar um pouco como um IWForm está se comportando quando usamos processamento do lado cliente.

Propriedade “HiddenFields”

Aqui podemos criar inputs hidden dinamicamente para nossas páginas (Isso é novidade). No String List Editor digite:

GMottaZn=VariaveisOuConstates_PraQuemGosta_do_InputHidden
CoisasLoucas=Bla




Propriedade “ExtraHeader” do IWForm1

Digite o código Javascript na propriedade do IWForm1 conforme ilustrado abaixo:

<SCRIPT LANGUAGE="JavaScript">
<!-- Exibindo informações sobre o browser ...
document.write("<HR>");
document.write("<H1><center><font color=#0080C0 size=5 face=Geneva,
Arial, Helvetica, sans-serif>Estação ZN - Client Side Scripting
</font></center></H1>");
document.write("<HR>");
document.write(" <br>A versão do browser: " + navigator.appVersion);
document.write(" <br>Marca: <B>" + navigator.appName +
"</B>.");
// end script hiding -->
</SCRIPT>




Propriedade JavaScript do IWForm1
Vou criar algumas funções JavaScript e veremos o que vai acontecer. A propriedade JavaScript declaramos apenas funções porque a tag “script type” é definida pelo framework. Diferente do que experimentamos da propriedade “ExtraHeader”.


// Percorre o objeto HTML "form". O Intraweb cria todos os objetos HTMLs
a partir do seu form "Delphi"
function ZnShowObjects(){
for (var j = 0; j < document.forms[0].elements.length; j++) {
alert("Loop volta = "+j);
alert(document.forms[0].elements[j].name + ": " +document.forms[0].elements[j].value);
ZnInput = document.forms[0].elements[j];
alert("Bla");
alert(ZnInput.getAttribute("type"));
if (ZnInput.getAttribute("type").toLowerCase() == "hidden"){
alert(ZnInput.getAttribute("type"));
}
}
};

//função para exibir o input hidden que criamos na propriedade "HiddenFields"

function ExibeHidden(){
MyZn = document.getElementById("GMottaZn");
alert(MyZn.type + "|" + MyZn.name + " = "+ MyZn.value);
};

//Exemplificando uma estrutura de repetição "while" em JavaScript
function ExibeEscondido(){
MyZn = document.getElementById("GMottaZn");
alert("Veja o input hidden que criamos:" + MyZn.value);
ZnInputs = document.forms[0].getElementsByTagName('input');
Achei = 0;
i = 0;
// exemplificando o método "getElementsByTagName", ele retorna uma lista de objetos HTML
while (AZnInput = ZnInputs[i]){
alert("while");
// Procurando o hidden na lista retornada pelo "getElementsByTagName"
if (AZnInput.getAttribute('type').toLowerCase() == 'hidden'){
alert("Achei um escondido!! :" + AZnInput.name + " - "+
AZnInput.value);
Achei = Achei++;
}
else {
// Não encontrou o hidden
alert("Não é hidden: " + AZnInput.name + " - "+
AZnInput.value);
};
i++;
};
if (Achei == 0) {
alert("Não encontra os escondidos, mas eles estão lá!!!");
}
else {
alert(Achei);
};
};


Agora vamos adiciona os controles no IWF3orm1:
Adicione da plaheta IWStandard um TIWEdit, e três TIWButtons.



Testei a propriedade “ExtraTagParams” dos controles, sem sucesso por enquanto. Vou tentar mais posteriormente.



Na propriedade “ScriptEvents” da cada um dos IWButtons fiz a chamada a cada uma das funções que definimos na propriedade “JavaScript” do IWForm1. Veja as imagens abaixo e codifique igual:


IWButton1 - OnClick


IWButton2 - OnClick


IWButton3 - OnClick


Para executar a aplicação pressione F9. Vai aparecer o diálogo do simulador de servidor web, pressione F9 novamente.








Artigo completo (View Full Post)

segunda-feira, 23 de junho de 2008

Linq to SQL - Working with Databases

Clique aqui para ver a versão em português deste post

In this post I continue to show the Linq technology. This tiime we'll see how it's used to access and manipulate data in relational database tables.

In order to use Linq with databases we need to establish a relationship between the business objects in our software and the database tables. To achieve this we use the class/attributes mapping.

This mapping is simple: We create a class that represent a database table and in this class we set which table it is mapped to. In the attributes we set to which database fields they're mapped.

In the current version, Linq only supports the MS SQL Server, but there are already many developers out there working on solutions to cover other RDBMSs too.

To begin let's show a table in the database: Produtos

CREATE TABLE [dbo].[Produtos](
[ProdutoID] [uniqueidentifier] ROWGUIDCOL
NOT NULL CONSTRAINT [DF_Produtos_ProdutoID] DEFAULT (newid()),
[Descricao] [nvarchar](100) COLLATE Latin1_General_CI_AS NOT NULL,
[Preco] [decimal](10, 2) NOT NULL,
[Saldo] [int] NOT NULL,
[Versao] [timestamp] NOT NULL
)


Let's pay close attention at the column Versao, type timestamp. This datatype stores the record version. This is very useful to work with optimistic updates and concurrency issues and Linq makes good use of it.

Before we advance, insert some records in this table.

Now let's create a class that uses this table. In order to use Linq to SQL we need to add reference to the assembly System.Data.Linq to the project. Here is the code:

using System;
using System.Data.Linq.Mapping;

[Table(Name="Produtos")]
class Produto {

[Column(IsPrimaryKey = true,
IsDbGenerated = true,
AutoSync = AutoSync.OnInsert)]
public Guid ProdutoID { get; set; }

[Column(CanBeNull = false)]
public string Descricao { get; set; }

[Column(CanBeNull = false)]
public decimal Preco { get; set; }

[Column(CanBeNull = false)]
public int Saldo { get; set; }

[Column(IsDbGenerated = true,
IsVersion = true, AutoSync = AutoSync.Always)]
public System.Data.Linq.Binary Versao { get; set; }
}


Now let's create a Linq query in this database table. Up until here we just defined the entity and attributes mapping, but we didn't define anything about the database itself. How do we do that?

There is an object in Linq called DataContext. We can think of it more like a database connection in other technologies, but it hardly acts like. It does so much more! It's responsible for the database connection, making and the exectution of the queries, mapping, record updates and even transactions and record concurrency!

We just need to create a instance and it does everything on its own. In other words, we don't need to make code to open or close connection, build string queries and treat results anymore. Let's see the code:

using System;
using System.Data.Linq;
using System.Linq;

class Program {
static void Main(string[] args) {

var connStr = @"Data Source=.\SQLEXPRESS;Initial Catalog=DadosSql;User ID=felipe;Password=123";

using (var db = new DataContext(connStr)) {
var Produtos = db.GetTable<Produto>();

var qry =
from p in Produtos
orderby p.Descricao
select p;

foreach (var prod in qry) {
Console.WriteLine("{0}, {1}, {2}", prod.Descricao,
prod.Preco,
prod.Saldo);
}
}
}
}


What we've done:

- Created a DataContext to connect to the database;
- Created a local variable to represent our mapped table;
- Built the query;
- Display the results;

The wonder of wonders is: Will the DataContext retrieve the entire Produtos table when we create the local variable Produtos? Answer is no! Then, will it occur when we create the qry? Nope. So, where is it?

One of the coolest things in Linq is the ability to send the query to the database only at the moment its data is actually required. In our case, in the foreach loop. That query returned an instance of IOrderedQueryable that seems like a List. But it isn't quite a common list. When its data is required the DataContext build a query based on its definition and send the query to the database and then convert the resultset in an object list, thanks to the mapping features. This technique is called Deferred execution.

How would we do in order to open connection, build a parametrized query and convert the resultset in a list of instances of our business object? And all other tables?

I'll change the code a bit and add some verbose. The DataContext has a property called Log that allows us to view the DataContext's log:

using System;
using System.Data.Linq;
using System.Linq;

class Program {
static void Main(string[] args) {

var connStr = @"Data Source=.\SQLEXPRESS;Initial Catalog=DadosSql;User ID=felipe;Password=123";

using (var db = new DataContext(connStr)) {
db.Log = Console.Out;

Console.WriteLine("** Pegando a tabela Produtos");
var Produtos = db.GetTable<Produto>();

Console.WriteLine("** Criando a query");
var qry =
from p in Produtos
where p.Descricao.Contains("a")
orderby p.Descricao
select p;

Console.WriteLine("** Começando a iteração");
foreach (var prod in qry) {
Console.WriteLine("{0}, {1}, {2}", prod.Descricao,
prod.Preco,
prod.Saldo);
}
}
}
}


Here's the console output:

** Pegando a tabela Produtos
** Criando a query
** Começando a iteração
SELECT [t0].[ProdutoID], [t0].[Descricao], [t0].[Preco], [t0].[Saldo], [t0].[Ver
sao]
FROM [Produtos] AS [t0]
WHERE [t0].[Descricao] LIKE @p0
ORDER BY [t0].[Descricao]
-- @p0: Input NVarChar (Size = 3; Prec = 0; Scale = 0) [%a%]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.21022.8

Caderno Universitário 500 folhas, 7,90, 50
Caneta BIC, 1,99, 25
Lapiseira 0,7mm, 5,00, 10
Pasta polionda A4, 2,40, 6


The DataContext produces a query with parameters, instead of concatenate the criteria and build one simple query string. This is very nice, because the RDBMS can make an execution plan for this query and use the same play every time we run this query, even with different parameter values. It means better performance.

Well, that's it for this post, but Linq to SQL goes way further than this. In the next issue I'll write about CRUD operations with Linq to SQL. Thnnk you and take care.

Artigo completo (View Full Post)

Linq to SQL - Trabalhando com bancos de dados

Click here to see this post in English

Neste post vou continuar a mostrar sobre a tecnologia Linq. Desta vez veremos como ela é usada para acessar e manipular dados em tabelas de bancos de dados relacionais.

Para habilitar Linq para acessar bancos de dados nós precisamos primeiro estabelecer relações entre os objetos de negócio do nosso software e as tabelas do banco de dados. Para isso usamos mapeamento de classe/abtributos.

Este mapeamento é simples: Nós criamos uma classe que representa uma tabela do banco de dados e nesta classe nós indicamos qual tabela do banco de dados ela representa. Nas propriedades desta classe nós marcamos quais propriedades representam quais campos da tabela.

Na versão atual Linq suporta apenas o MS SQL Server, mas há desenvolvedores por aí que já estão trabalhando no suporte a outros bancos também.

Para começar vamos mostrar uma tabela no banco de dados: Produtos

CREATE TABLE [dbo].[Produtos](
[ProdutoID] [uniqueidentifier] ROWGUIDCOL
NOT NULL CONSTRAINT [DF_Produtos_ProdutoID] DEFAULT (newid()),
[Descricao] [nvarchar](100) COLLATE Latin1_General_CI_AS NOT NULL,
[Preco] [decimal](10, 2) NOT NULL,
[Saldo] [int] NOT NULL,
[Versao] [timestamp] NOT NULL
)


Atenção especial à coluna Versao, do tipo timestamp. Esta coluna armazena a versão do registro. Ela é útil para efeitos de atualizações otimistas e concorrência e Linq faz ótimo uso dela.

Antes de continuar insira alguns registros nesta tabela.

Agora vamos codificar uma classe que faça uso desta tabela. Para utilizar Linq devemos adicionar referência no projeto para o assembly System.Data.Linq. Abaixo segue o código da classe:

using System;
using System.Data.Linq.Mapping;

[Table(Name="Produtos")]
class Produto {

[Column(IsPrimaryKey = true,
IsDbGenerated = true,
AutoSync = AutoSync.OnInsert)]
public Guid ProdutoID { get; set; }

[Column(CanBeNull = false)]
public string Descricao { get; set; }

[Column(CanBeNull = false)]
public decimal Preco { get; set; }

[Column(CanBeNull = false)]
public int Saldo { get; set; }

[Column(IsDbGenerated = true,
IsVersion = true, AutoSync = AutoSync.Always)]
public System.Data.Linq.Binary Versao { get; set; }
}


Agora vamos criar uma query Linq nesta tabela do banco. Até aqui nós definimos o mapeamento da entidade e dos campos, mas nós não definimos nada sobre o banco de dados. Como faremos isso?

Há uma classe em Linq chamada DataContext. Podemos pensar nela como se fosse um objeto de conexão com um banco de dados, mas o DataContext vai além disso. Ele é responsável pela conexão com o banco de dados, montagem e execução das queries, tratamento dos resultados, cuida das operações de atualização dos registros e até cuida de transações e concorrência de registros!

Para isso só devemos instanciá-lo e ele faz tudo automaticamente! Ou seja, nós não precisamos mais criar códigos para abrir conexão, fechar conexão, montar queries em string, tratar resultados... Vamos ver na prática:

using System;
using System.Data.Linq;
using System.Linq;

class Program {
static void Main(string[] args) {

var connStr = @"Data Source=.\SQLEXPRESS;Initial Catalog=DadosSql;User ID=felipe;Password=123";

using (var db = new DataContext(connStr)) {
var Produtos = db.GetTable<Produto>();

var qry =
from p in Produtos
orderby p.Descricao
select p;

foreach (var prod in qry) {
Console.WriteLine("{0}, {1}, {2}", prod.Descricao,
prod.Preco,
prod.Saldo);
}
}
}
}


Vamos repassar:

- Criamos um DataContext para conectar ao nosso banco de dados;
- Criamos uma variável local para ser a definição da nossa tabela mapeada;
- Fazemos a query extraindo dados desta "tabela";
- Exibimos os resultados.

A parte mais legal é: Será que o DataContext vai trazer a tabela Produtos inteira quando passar pela linha de código onde criamos a variável Produtos? A resposta é não! Então, quando o banco vai na tabela Produtos? Na linha onde criamos a qry? Também não! Ora, então onde é?

Uma das características mais legais do Linq to SQL é a habilidade de executar a query no banco apenas no momento em que seus dados são utilizados. No nosso caso, no loop foreach. Aquela query produziu a variável qry do tipo IOrderedQueryable que, parece, é uma lista. Tem até foreach! Mas ela não guarda as informações nela no momento em que é instanciada. Quando o software "requer" os dados desta "lista", ela produz uma instrução SQL select e traz do banco os resultados, transformando-os em uma coleção de instâncias da classe Produto, através do mapeamento. Isso é chamado Deferred execution.

Como iríamos fazer para abrir conexão com o banco de dados, criar uma query parametrizada e transformar um resultset de datarows em uma lista de instâncias de Produto? E para todas as outras tabelas?

Para reforçar o que foi dito acima, vamos ver o log do DataContext para ver o que ele faz e como faz. Vou adicionar algumas linhas de código ao nosso exemplo anterior e ele vai ficar assim:

using System;
using System.Data.Linq;
using System.Linq;

class Program {
static void Main(string[] args) {

var connStr = @"Data Source=.\SQLEXPRESS;Initial Catalog=DadosSql;User ID=felipe;Password=123";

using (var db = new DataContext(connStr)) {
db.Log = Console.Out;

Console.WriteLine("** Pegando a tabela Produtos");
var Produtos = db.GetTable<Produto>();

Console.WriteLine("** Criando a query");
var qry =
from p in Produtos
where p.Descricao.Contains("a")
orderby p.Descricao
select p;

Console.WriteLine("** Começando a iteração");
foreach (var prod in qry) {
Console.WriteLine("{0}, {1}, {2}", prod.Descricao,
prod.Preco,
prod.Saldo);
}
}
}
}


Olha aqui a saída do console:

** Pegando a tabela Produtos
** Criando a query
** Começando a iteração
SELECT [t0].[ProdutoID], [t0].[Descricao], [t0].[Preco], [t0].[Saldo], [t0].[Ver
sao]
FROM [Produtos] AS [t0]
WHERE [t0].[Descricao] LIKE @p0
ORDER BY [t0].[Descricao]
-- @p0: Input NVarChar (Size = 3; Prec = 0; Scale = 0) [%a%]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.21022.8

Caderno Universitário 500 folhas, 7,90, 50
Caneta BIC, 1,99, 25
Lapiseira 0,7mm, 5,00, 10
Pasta polionda A4, 2,40, 6


A query que o DataContext produziu foi parametrizada, em vez de ter os valores concatenados. Isso é muito bom, porque o SGBD faz o plano de execução e deixa ele em cache, para que outras consultas que apenas tenham parâmetros diferentes usem o plano de execução que já foi calculado, trazendo melhor performance.

Com isso chegamos ao fim da nossa primeira visão sobre Linq to SQL e em outros posts vamos ver sobre as oeprações de CRUD com Linq to SQL. Até lá e muito obrigado.

Artigo completo (View Full Post)

domingo, 22 de junho de 2008

Chromazone - Guitar and Bass

Nas horas não vagas, quando preciso zerar a mente, sentir como se ela fosse um papel em branco, encontro na música uma forma rápida e eficiente de atingir este estado. O tema do momento no meu momento é o “ultimate-extreme-hardcore” Choramazone. Sem sombra de dívida uma zona radical, contundentemente adiatônica, paradoxalmente polirrítmica. Essa música da onda .... hehehehhe
Corrigi alguns compassos da partitura que postei anteriormente. Contudo, não está academicamente perfeita, mantive a imperfeição conveniente e agradável, mas com um pouco de boa vontade dá pra entender tudo direitinho que está escrito (hehehhe).
Além disso, escrevi a partitura do baixo (Bass - score). Deu um trabalhinho fazer essa transcrição, estou sem prática. Apesar disso, foi mto prazeroso absorver esse groove (da melhor qualidade). Procurei a rodo na Internet, não achei nenhuma partitura (transcrita) do baixo do Chromazone, as vezes fico abismado como esse tipo de conteúdo é raro na web. Acho lamentável e não consigo entender pq!
O próximo passo será partir para os improvisos. Isso vai ser pedrera, um solo do Stern e um do Brecker!!! Aula de pós-graduação! Bem, se eu sobreviver ... vai ser relatado aqui ... hhehehhe.
Chega de papo ... segue as partituras:


página 1 de 4


página 2 de 4


página 3 de 4



página 4 de 4

Cavadas ...

Bass:

página 1 de 2



página 2 de 2


Guitar:

página 1 de 2




página 2 de 2



Artigo completo (View Full Post)

sábado, 21 de junho de 2008

Finalmente Zerei o Resident Evil 4

Olá olá olá!!!

Desculpem tomar o espaço do blog dessa maneira mas eu finalmente consegui zerar o Resident Evil 4 do PS2! Eu não acreditava mas o jogo é um dos melhores que eu já joguei até hoje. Se existe por aí alguma outra pessoa no mundo (eu acho que sou a única pessoa do mundo que ainda não tinha terminado este jogo hehe) que ainda não tenha jogado, eu recomendo. Ótimas horas de diversão. Não se esqueça de também completar os jogos extras que liberam. Eu joguei o Assignment Ada e o Separate Ways e achei absurdo - muito maneiro.

Veja o que o gamespot fala sobre este jogo.

No mais estou terminando mais um post sobre Linq e vou postar aqui assim que eu terminar. Grande abraço a todos e até a próxima!

Artigo completo (View Full Post)

quinta-feira, 19 de junho de 2008

Delphi & JavaScript - IntraWeb

IntraWeb



Trata-se de um framework, desenvolvido pela Atozed, incorporado ao Delphi na versão 7. É uma suíte de desenvolvimento RAD (Rapid application development – Aplicação de desenvolvimento rápido) para web, na época em que foi lançada se apresentou no mercado, comparativamente com as demais tecnologias, extremamente poderosa. Por volta de 2004 e durante os anos seguintes, o IntraWeb fez do Delphi 7 um marco no desenvolvimento de aplicações sob o protocolo “http”.
Os componentes IW são extendidos da VCL tornando possível que o desenvolvimento com está tecnologia seja semelhante a um projeto desktop. Essa, na minha opinião foi uma característica importante do IntraWeb, visto que sua adoção por um profissional oriundo do ambiente “off-line” minimizou sensivelmente tanto o impacto, quanto a curva de aprendizagem dos novos conceitos concernentes ao ambiente web.
O IntraWeb permite, a partir de um form (web form), adicionar componentes, inclusive dataware, escrever códigos para os eventos dos mesmos e atribuir valores para suas propriedades (da mesma maneira que os desenvolvedores já faziam desde o Delphi 1). Pronto, eis o seu sistema ou site para Intranet, ou Internet! Tudo isso usando o boa e velha Delphi Language.
Esse framework ainda está presente nas novas versões do Delphi, contudo, ao que parece, são raros os projeto hoje que o utilizam. Acredito que a causa mais determinante para isso é o caráter fechado, proprietário, pois a Atozed não disponibilizou nem os fontes, nem mesmo uma documentação adequada do produto. Além disso tentou “arquitetar” um lance “mercadológico genial” de disponibilizar para venda versões supostamente mais estáveis e poderosas que ela havia incorporado ao Delphi. Não preciso gastar muitas linhas para descrever aonde ela chegou com essa estratégia genial.
Apesar disso, é possível conseguir em resultado bastante satisfatório usando o IntraWeb.

Javascript

“Linguagem de script, orientada a objetos, que permite a programação do lado cliente”.
O Javascript permite que haja processamento em resposta a interação do usuário com a página (no chamado “lado cliente”), sem a necessidade de remetê-la para ser processada no servidor. Isso se torna extremamente útil nos casos em que esse processamento não é exclusivamente necessário no servidor, visto que a dinâmica de requisição/resposta tem custos: o próprio processamento, que demanda do servidor recursos, e o fluxo na rede, que é um gargalo pro seu sistema. Por exemplo, a validação de valores digitados nas caixas de texto, como CPF, datas, valores nulos, e-mail e etc., são casos que podem, e devem, ser processados do lado cliente.

CSS

Cascading Style Sheets (Folhas de Estilo em Cascata): Permite controlar a aparência da página. Isso influencia diretamente o design do seu site ou aplicação web. Ao utilizar o CSS você pode especificar o estilo dos elementos que formatam a página (espaçamento, margens, tipo e tamanho de fonte) separadamente da estrutura dela (cabeçalhos de seção, títulos, corpo do texto e links). Essa separação da estrutura do conteúdo permite maior gerenciabilidade tornando, se necessária, qualquer mudança no estilo do site muito mais fácil e rápida.

DHTML

A Dynamic HTML foi projetada para que uma aplicação web possa ser construída de forma que grande parte de suas funcionalidades sejam executadas diretamente no lado cliente, ao invés do lado servidor. Ela faz as páginas web tornarem-se muito mais interativas fornecendo efeitos multimídia que incluem animação, áudio e vídeo. Ora, mas o Javascript não possui o mesmo objetivo? Então, o que é exatamente o DHTM? Basicamente a DHTML permite que os elementos do HTML possam ser tratados como objetos. Logo, torna possível manipular os valores dos atributos desses elementos como propriedades. A manipulação dessas propriedades é feita através do Javascript, ou qualquer outra linguagem de script como o JScript, ou VBScript, por exemplo. A DHTML da Microsoft é incompatível com a da Netscape, portanto, saiba que a utilização desta técnica pode lhe trazer problemas. Por isso é imprescindível que testes sejam realizados nos diferentes navegadores, pelo menos nos mais usados, se você optar por utilizar a DHTML.

Criando a plicação web para teste

Começaremos nosso primeiro exemplo criando um novo projeto IntraWeb no Delphi. Antes de Qualquer coisa crie um diretório para salvarmos nosso exemplo em: C:\Exemplo_1.

Agora podemos voltar ao Delphi, no menu "File" - "New" click em "Other". Em seguida, no repositório de objetos escolha, na aba IntraWeb, Stand Alone Aplication.




O próximo passo será salvar a aplicação iniciada em “c: Exemplo_1”.



Aperte “Ctrl + F12”, selecione IWUnit1 e click “OK” para chamarmos o form Intraweb.





Form IntraWeb (TWIForm)

O TIWForm é o componente IntraWeb similar ao TForm da VCL, através deste componente o Delphi gera páginas web. Nele podemos definir o estilo CSS que será usado para o design da página, também podemos programar scripts do lado cliente e desta forma extrair o máximo do paradigma web.





ExtraHeader

Começaremos pela propriedade do ExtraHeader do TIWForm, nela podemos adicionar qualquer tag com código dentro da seção Head (que é definida pela tag “<head> </head>” de uma página HTML). O browser interpreta o conteúdo da tag head antes da tag body , deste modo podemos tanto escrever programas em Javascript para serem executados imediatamente no momento em que a página é renderisada pelo navegador, quanto podemos codificar funções que serão executadas mediante uma determinada interação do usuário com o browser. Você pode usar o editor do
DreamWeaver para lhe auxiliar a criar as funções em Javascript.



O código na anterior deve ser colocado na propriedade ExtraHead do TformMain. Para isso, com o TIWForm selecionado, vá ao Object inspector e click na propriedade ExtraHeader.



StringList Editor



Segue o código:

<script type="text/javascript">
document.writeln("<center> <h1> <font face= 'Australian Sunrise' color=#220099> Javascript no Itraweb - powered by Delphi</font> </h1> </center>");
var shadowDirection = 0;
function iniciar(){
window.setInterval("demostrar()",500);
}

function demostrar(){
shadowText.filters("shadow").direction = (shadowDirection % 360);
shadowDirection += 15;
}
</script>


Para executarmos a função iniciar adicionaremos ao Form um TIWButton e um IWLabel da palheta IWStandard. Na tabela a baixo veja como configura-los.



Configuraçao dos Componentes

TIWButton: Name = BtConfirmar, Top = 360, Left = 350, Caption = Confirmar

TIWLabel: RawText = True, Caption = <h2 id = "shadowText" style= "position:absolute; top:120px; left:340px; filter: shadow(direction = 0, color = #220099)"><font face="Australian Sunrise" color="#FF6633"> DHTM - Dynamic HTML </font></h2>


Depois de adicionar o código que vai definir o texto animado na propriedade caption do IWLabel1 a aparência fo IWForm ficará semelhante a figura abaixo:



Codifique a unit “IWUnit1” conforma exemplificado abaixo:

Crie uma procedure na seção public para validar campos vazios em JavaScript. Essa função criará uma critica dinamicamente para cada componente que possuir um valor na propriedade FriendlyName iniciando por “v_”.

procedure TformMain.Validacao;
var i: Integer;
Funcoes: array of TStringList;
EditAtual: TIWCustomEdit;
begin
{esta funçao monta o java script na página. Lembre-se de, no FriendlyName do Edite ou memo, iniciar com "V_" .
Depois no evento scripEvent do IWbutton chamar a função ValidaEmBranco() }
Self.JavaScript.Add('function ValidaEmBranco() {');
SetLength(Funcoes, Self.ComponentCount);
for i := 0 to Pred(Self.ComponentCount) do
begin
if (Self.Components[i] is TIWCustomEdit) then
begin
EditAtual := TIWCustomEdit(Self.Components[i]);
if Copy(EditAtual.FriendlyName, 1, 2) = 'v_' then
begin
Funcoes[EditAtual.TabOrder] := TStringList.Create;
with Funcoes[EditAtual.TabOrder] do
begin
Add(#13#10);
Add(' if (document.forms[0].' + UpperCase(EditAtual.Name) + '.value == "") {');
Add(' alert("Preencha o campo ' + Copy(EditAtual.FriendlyName, 3,
Length(EditAtual.FriendlyName)) + '");');
Add(' document.forms[0].' + UpperCase(EditAtual.Name) + '.select();');
Add(' return false;');
Add(' }');
end;
end;
end
end;

for i := 0 to Pred(Length(Funcoes)) do
if not (Funcoes[i] = nil) then
Self.JavaScript.Add(Funcoes[i].Text);

Self.JavaScript.Add(' return true;');
Self.JavaScript.Add('}');
end;


No evento "OnCreate" do formMain digite:


procedure TformMain.IWAppFormCreate(Sender: TObject);
begin
Validacao;
end;



Na propriedade ExtraTagParams do BtConfirmar digite:

onClick=ValidaEmBranco();


Adicione ao formMain um TIWEdit da palheta IWStandard. Apague o valor da propriedade Text, em seguida altere o valor da propriedade "FriendlyName" para v_IWEdit1. Para que nossa função para efetuar a crítica conforme espera a procedue "Validacao" que criamos anteriormente.

Para executar a plicação basta apertar o F9, ou no menu "Run" selecionar "Run".



Artigo completo (View Full Post)

domingo, 15 de junho de 2008

Identificadores e Palavras Reservadas - Java

Identificadores e Palavras Reservadas

Identificadores é o que usamos para nomear variáveis, instâncias de classe (que também são variáveis), constantes, métodos e propriedades. Em outras palavras, identificador é tudo que não seja um literal, nem símbolos ou números, nem palavras reservadas. Existem regras que determinam como devem ser declarados os identificadores permitidos em Java (igualmente como em qualquer outra linguagem de programação. Pelo menos, até os dias de hoje). Além dessas regras de sintaxe, a Sun define uma convenção para nomeação de métodos, variáveis e classes. Semelhantemente as demais linguagens de programação, em Java existe um conjunto de palavras reservadas para a linguagem. Isso implica que não é possível usá-las para nomearmos identificadores. Mais tarde falarei detalhadamente sobre a convenção para criação de identificadores para métodos, propriedades e classes em Java.

Obs: Ok, anteriormente escrevi sobre a mesma coisa com uma outra abordagem acho que se vc ainda tem alguma dúvida sobre esse tema pode encontrar ....

Cabe destacar que a adoção de uma padronização quanto a codificação é comum em muitas linguagens de programação, falaremos sobre isso mais tarde.

Regras para nomeação de Identificadores



A sintaxe da linguagem Java define as seguintes regras para se declarar identificadores:

Os identificadores devem começar com uma letra, ou cifrão ($), ou Underscore ( _ ). Não é permitido caracteres numéricos para iniciar um identificador.

Palavras reservadas não podem ser usadas como identificadores.

A linguagem Java é case sensitive (sensível a caixa) para identificadores. Exemplo: Cliente e cliente são, para o compilador, identificadores diferentes.

Não há limite para o número de caracteres usados para compor um identificador.

Exemplo de identificadores grafados de forma correta:

int _a;
String $Coisas;
double _$;
double um_Exemplo_de_nome_bastanteZn_Prolixo_para_um_identificadorZn;

Em seguida veja exemplos de identificadores declarados de forma não aceitável para o compilador.

int :b;
int -di
int e#;
int .f;
int 79;


Exemplo de um programa em Java para testarmos as regras sobre identificadores citadas:
Primeiro veremos um programa “dummy” cujo os identificadores criaremos de forma convencional.


import javax.swing.JOptionPane;
/**
*
* @author Gerson
*/
public class Main {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
String znSaida = "";
int EstacaoZn = 2;

for (int i = 1; i <= 10; i++){ if (i == 5) continue; znSaida += i + " "; } znSaida += "\n bleng Zn! Skip --> 5";
JOptionPane.showMessageDialog(null, znSaida);
System.exit(0);
}

}



Segundo veremos o mesmo programa “dummy”, contudo alteraremos os nomes dos identificadores para as situações específicas definidas pelo Java 5.

Criando um novo projeto no NetBeans





Definindo o diretório onde o projeto seja salvo





/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package exemploidentificadoreszn2;

import javax.swing.JOptionPane;
/**
*
* @author GMottaZn
*/
public class Main {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
String _znSaida = "";
int $EstacaoZn = 2;
String um_Exemplo_de_nome_bastanteZn_Prolixo_para_um_identificadorZn;
for (int i = 1; i <= 10; i++){ if (i == 5) { $EstacaoZn = (4 + $EstacaoZn); continue; } else{ $EstacaoZn = (10 + $EstacaoZn); um_Exemplo_de_nome_bastanteZn_Prolixo_para_um_identificadorZn = "Estaçao ZN = "; } ; _znSaida += i + " " + um_Exemplo_de_nome_bastanteZn_Prolixo_para_um_identificadorZn; } _znSaida += "\n bleng Zn! Skip --> 5 - $EstacaoZn = " + $EstacaoZn;
JOptionPane.showMessageDialog(null, _znSaida);
System.exit(0);
}

}




Artigo completo (View Full Post)

Abordagem OO Java - Introdução

Recorrentemente temos abordado POO aqui no blog. Nosso foco maior tem sido Delphi e C#, contudo sempre que podemos procuramos ampliar nossos exemplos experimentando outras linguagens. Vamos falar um pouco desse contexto no mundo Java.

Breve revisão sobre Java

Um programa em Java é sempre uma coleção de objetos comunicando-se com outros. Comunicação essa que acontece mediante a chamada de métodos (evocação de métodos) uns dos outros. Nunca esquecendo, de ter sempre em mente que cada objeto é de um determinado tipo, definido por uma classe ou interface. Não desprezado o fato dessa coleção de objetos, a qual mencionei anteriormente, ser quase sempre composta por objetos de uma variedade diferente de tipos. Vejamos as seguintes definições sobre OO (Estou usando como referência para este artigo o livro da Kathy Sierra, certificação Sun (Java 5), primeiro capítulo):


Classe:
Um modelo que descreve os tipos, de estado e de comportamento, que os objetos do seu tipo podem ter.

Permita-me um comentário: Particularmente, eu acho essa definição satisfatória para quem já conhece bem orientação a objetos. Contudo, para quem esta aprendendo programação ou vem de uma cultura de programação estruturada, duvido que o parágrafo anterior agregue algum valor, no que tange o processo cognitivo de quem o está lendo. Em outros artigos eu e o Felipe usamos outras abordagens para este conceito. Sugiro que você complemente o entendimento lendo as demais definições, principalmente se você ainda esta dando os primeiros passos em OO.

Objeto:
No momento da execução do programa, quando a JVM (Java Virtual Machine) encontra a palavra reservada “new” ela cria uma instância da classe, referenciada no trecho de código corrente. A isso chamamos de criar um objeto (em outras palavras: instanciar um objeto). Esse objeto recém criado terá seu próprio estado, bem como um comportamento. O qual será expressado como reflexo de todas as funcionalidades, definidas por métodos na classe, que são dinamicamente acessíveis ao objeto.
Quem são essas classes acessíveis ao objeto??? Isso se refere a herança. Um objeto cujo tipo é, por exemplo, uma classe “X” terá acesso ao comportamento de todos os ancestrais dela. Ou seja, ele poderá se comportar como a classe “X”, a classe “XPai”, bem como a classe “XAvo” e assim sucessivamente até o ancestral mais alto (o qual chamamos de super classe). Falaremos mais sobre herança adiante.

Estado:
Variáveis de instância – Cada objeto (que por sua vez é uma instância de uma classe) terá seu conjunto único de variáveis de instância conforme definido na classe (definidos pelos atributos da classe). Em contra partida, coletivamente os valores atribuídos as variáveis de instância de um objeto, expressam o estado do mesmo. Ou, os valores persistidos pelas propriedades do objeto, expressam o estado do mesmo.
Ou seja, o conjunto de atributos do objeto definirá, a partir dos valores definidos neles, o estado desse objeto. Por exemplo: Suponha que temos um objeto “Lâmpada”, esse objeto é possuidor de um conjunto de atributos: Potência, Voltagem, Cor e etc. Devemos considerar que este objeto, além desses, possua outro atributo que definirá se “Lâmpada” esta acesa ou não. Esse atributo pode se chamar “Ativa”, ele indica se ela está acessa (ou seja, ativa) ou não. Logo, quando todos esses atributos possuírem valor, exemplo: Lâmpada.Cor = Amarela, Lâmpada.Voltagem = 110, Lâmpada.Potência = 100W e Lâmpada.Activa = Verdadeiro. Posso agora então conhecer o estado desse objeto.

Comportamento:
Quando codificamos uma classe, e implementamos os métodos dela, estamos definido a lógica da classe. “É nos métodos que a lógica da classe é armazenada” (Achei essa definição muito apropriada). Através dos métodos, o verdadeiro trabalho da classe é realizado. Ou seja, a razão de ser da classe, onde seu principal objetivo é definido. Neles e por meio deles, algoritmos são executados e os dados são manipulados.

Herança:
Característica da orientação a objetos que permite o reaproveitamento do código de uma classe por outra. Em Java é possível definir uma superclasse “genérica” (mais abstrata) e em seguida estendê-la criando outras classes mais específicas. A superclasse não tem conhecimento algum sobre as classes que descendem dela. Em contra partida, essas classes herdeiras precisam declarar explicitamente a relação de herança. Como efeito disso, uma subclasse que herda de uma superclasse “recebe automaticamente”, digamos assim, as variáveis de instância acessíveis, bem como os métodos definidos na superclasse. Além disso possui autonomia para redefinir os métodos herdados da superclasse, a fim de expressar um comportamento mais específico (este fenômeno chamamos de sobrescrita de método. Ou seja uma subclasse pode sobrescrever os métodos herdados).

Identificando Classes (Análise)
Em concordância com o que mencionei anteriormente, é extremamente importante ser obstinado em alcançar um grau de coesão alto na classe que você está definindo. Isso implica diretamente que toda classe deve ter muito bem definido o conjunto de responsabilidades pertinentes ao conceito do mundo real o qual ela representará para um sistema. Por exemplo, imagine um programa cujo objetivo principal é simular uma orquestra: Certamente encontraremos a representação de instrumentos musicais por algumas classes, bem como músicos, partituras e composição musical por outras tantas. Concluir isso é bastante elementar. Contudo, um erro fatal (e na minha opinião muito freqüente) seria definir, em virtude de um equívoco de análise, o comportamento (ou parte dele) de uma classe em outra, ou vice-versa. Por exemplo: A classe instrumentista possuir um método que retorne o compasso corrente. Creeeeeddddooooo!??!?!?!? Visto que, compasso é um atributo da classe partitura. Um programa em Java é constituído tanto por classes construídas pelo programador, quanto por e outras que não (por exemplo, classes Java API). Em Java as classes são organizadas em pacotes, os quais devemos referenciar mediante a palavra reservada “import” a fim de usarmos suas classes em nossos programas. Dessa forma a linguagem fornece uma forma consistente do desenvolvedor nomear, bem como obter acesso, as classes que necessitar. No exame de certificação Java a avaliação aborda muitos dos conceitos relacionados aos pacotes e acesso a classes. Posteriormente detalharemos mais esses temas.

Interfaces:
É uma espécie de superclasse cem por cento abstrata que define os métodos que uma subclasse deve suportar, mas não define como esse método deve se comportar (ou seja, não define come deve ser implementado). Exemplificando, uma interface "Instrumento Musical" pode declarar que todas as as classes de implementação de "Instrumento Musical" (estendidas dela) possuirão um método "reproduzirSom()". Contudo, a interface "Instrumento Musical" não fornece nenhuma lógica para para este método. Isso implica que a classe que implementar "Instrumento Musical" terá a responsabilidade de definir o comportamento dos métodos definidos na interface. Determinando então, desta forma, como cada instrumento irá se comportar particularmente.
Venho sentindo a necessidade de escrever sobre interface não é de hoje, entretanto ainda não consegui preparar um material que me agrade. Esse assunto esta na fila e considero extremamente pertinente.

Artigo completo (View Full Post)

 
BlogBlogs.Com.Br