logo
  • Home
  • Acerca
  • Autores
  • Faq
  • Rede
  Twitter   Feed-me! RSS!
Nov 19

Generics, como Scala trata o Problema de Generalização de Classes

Escrito por DClick Team em 1, 4, 6, AR, auto, back, bar, BI, blog, boolean, busca, case, class, classe, classes, codec, código, comparação, demo, err, erro, error, exemplo, explicação, for, function, Google, IE, if, image, int, Java, lista, mg, Motivação, NaN, O, on, operadores, Orientação, Orientação a Objetos, padrão, problema, pt, rest, RIA, Ria’s Geral, RoR, screen, Screencast, site, string, strings, Sun, TAT, Teste, Tutorial, Twitter, UI, uint, XP, zend @ 11 19th, 2010 | via http://blog.dclick.com.br/pt/ | Sem comentários
DClick Team
? X
  • Bookmarks

Blinkbits BlinkLists BlogLines Blogmarks Buddymarks CiteULike Co.mments Del.icio.us Digg Diigo

Fark Feed Me Links Furl Google Linkagogo ma.gnolia Mister Wong Newsvine Propeller Rawsugar

Reddit Rojo Simpy Sphinn Spurl Squidoo StumbleUpon Tailrank Technorati Yahoo

More »

Twitter!


Generics em Java = Type Parameters em Scala


A motivação para o uso de generics em Java é bem conhecida, e Scala resolve o mesmo problema, dando um nome diferente para a solução: Type Parameters. Podemos chamar também de Generic Types, o significado é o mesmo.

Criando uma lista de tipo específico




Vamos implementar uma lista ligada para valores String. Tente fazer você mesmo, implementando um classe para ser a célula da lista, e uma para ser a lista em si. A lista deve também conter métodos para adicionar, remover e buscar um elemento específico dado o índice.

Em um paradigma mais funcional por assim dizer, você pode acabar em uma implementação para a célula, parecida com a minha:

1
2
3
4
5
6
7
8
package br.com.dclick.typeparameters

abstract class StringListCell {
    def isEmpty: Boolean
    def next: StringListCell
    def setNext(n: StringListCell): Unit
    def value: String
}


1
2
3
4
5
6
7
8
package br.com.dclick.typeparameters

class StringEmptyCell extends StringListCell{
    def isEmpty = true
    def next: StringListCell = error(“empty”)
    def value: String = error(“empty”)
    def setNext(n: StringListCell) = error(“empty”)
}


1
2
3
4
5
6
7
8
9
package br.com.dclick.typeparameters

class StringValueCell(v: String) extends StringListCell{
    var nextElem: StringListCell = new StringEmptyCell
    def isEmpty = false
    def setNext(n: StringListCell) = nextElem = n
    def next: StringListCell =  nextElem
    def value: String = v   
}


Implementação diferente do usual, né? :)
Repare que criei dois tipos de célula: uma célula que está sempre vazia, e uma célula que contém de fato o valor a ser guardado. Fiz isso pois em Scala não existe (ou a idéia é não utilizar) null, assim a checagem é feita por células vazias e não por null. Como Scala utiliza código Java, é possível passar e receber valores nulos. Código puramente em Scala estão praticamente livres de NullPointerException, justamente por essa restrição com valores nulos. Vamos ver logo mais um caso em que é possível obter tal erro.
Em Scala uma das alternativas para execução de funções que devolvem null como resultado para certas circunstâncias, é o Option. Option, como o próprio nome sugere, se trata de um opção por devolver, ou não um valor. No caso de se devolver algum valor, deve-se devolver um Some contendo o valor. No caso de não se devolver o valor, deve-se devolver um None. Ambos são Case Classes, portanto não necessitam da palavra new, e possuem todas a propriedades que vimos em um post anterior.

Pensando em todas essas características da linguagem, cheguei nesta implementação para a lista, e usei uma abordagem recursiva. Vou mostrar o resultado:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package br.com.dclick.typeparameters

class StringList {
    var head: StringListCell = new StringEmptyCell
    var last = head
   
    def add(value: String): StringTypeList = {
        if (head.isEmpty) {
            head = new ValueCell(value)
            last = head
        }
        else {
            last setNext new ValueCell(value)
            last = last.next
        }
        this
    }
   
    def remove(index: Int, node: StringListCell): StringListCell = {
        if (node.isEmpty)
            new StringEmptyCell
        if (index == 0) {
            node.next
        }
        else {
            node.setNext(remove(index-1, node.next))
            node
        }
    }
   
    def get(index: Int, node: StringListCell): Option[String] = {
        if (node.isEmpty)
            None
        else
            if (index == 0)
                Some(node.value)
            else
                get(index-1, node.next)
    }
}


Outra implementação não muito convencional… mas mesmo assim não deixa de ser clara. Mesmo não send o foco do post, vou dar uma breve explicação: na lista guardo o último elemento, assim sei onde devo adicionar o novo elemento; na função add verifico se o início da lista está vazio para adicionar, ou se devo adicionar no final; na função remove se a célula passada estiver vazia devolvo uma nova célula vazia, se o índice atual for zero, ou seja, queremos remover o atual, devolvo o próximo, e como caso padrão seto o próximo item como sendo o resto da lista com o item correto removido (Repare que não funciona para remover o primeiro item, mas não é esse o intuito mesmo :p); na função get verificao se a célula está vazia, logo não devolvo nada, e itero no resto dos itens de maneira recursiva no caso padrão.

Para termos certeza que nossa lista está funcionando corretamente, criei o seguinte teste unitário usando JUnit4, que para utilizá-lo é muito fácil, como foi visto no post anterior.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package br.com.dclick
import br.com.dclick.typeparameters._
import org.junit._
import Assert._

class ListTest {

    @Test
    def testList = {
        val list = new StringList
       
        assertEquals(None, list.get(0, list.head))
       
        list add “1″ add “2″ add “3″ add “4″ add “5″ add “6″
       
        assertEquals(“1″, list.get(0, list.head).get)
        assertEquals(“2″, list.get(1, list.head).get)
        assertEquals(“3″, list.get(2, list.head).get)
        assertEquals(“4″, list.get(3, list.head).get)
        assertEquals(“5″, list.get(4, list.head).get)
        assertEquals(“6″, list.get(5, list.head).get)
        assertTrue(list.get(6, list.head).isEmpty)
       
        list.remove(1, list.head)
        list.remove(1, list.head)
        list.remove(1, list.head)
       
        assertEquals(“1″, list.get(0, list.head).get)
        assertEquals(“5″, list.get(1, list.head).get)
        assertEquals(“6″, list.get(2, list.head).get)
        assertTrue(list.get(3, list.head).isEmpty)
    }
}


Rode o teste para ter certeza de que está tudo rodando.

Generalizando nossa Lista


Agora imagine que queremos fazer uma lista de inteiros ao invés de Strings. O problema é o mesmo que temos em Java. Se generalizarmos nossa lista para guardar AnyRef do Scala ao invés de Strings (em Java faríamos o mesmo com Object), teremos o problema de ter que fazer cast do resultado em toda chamada para nossa lista. Para isso que existem os Generic Types.

Se você reparou como utilizamos Option, tivemos que passar um tipo de parâmetro para ele, que no nosso caso foi String, dessa forma quem utiliza o resultado do método, sabe que está lidando com Strings e portanto não precisa fazer o cast do resultado. Vamos implementar a mesma funcionalidade em nossa lista. Para isso temos que modificar nossas células e nossa lista, de maneira que recebam o tipo como parâmetro. Segue o código da lista modificada:

1
2
3
4
5
6
7
8
package br.com.dclick.typeparameters

abstract class ListCell[T] {
    def isEmpty: Boolean
    def next: ListCell[T]
    def setNext(n: ListCell[T]): Unit
    def value: T
}


1
2
3
4
5
6
7
8
9
package br.com.dclick.typeparameters

class ValueCell[T](v: T) extends ListCell[T]{
    var nextElem: ListCell[T] = new EmptyCell[T]
    def isEmpty = false
    def setNext(n: ListCell[T]) = nextElem = n
    def next: ListCell[T] = nextElem
    def value: T = v
}


1
2
3
4
5
6
7
8
package br.com.dclick.typeparameters

class EmptyCell[T] extends ListCell[T]{
    def isEmpty = true
    def next: ListCell[T] = error(“empty”)
    def value: T = error(“empty”)
    def setNext(n: ListCell[T]) = error(“empty”)
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package br.com.dclick.typeparameters

class TypeList[T] {
    var head: ListCell[T] = new EmptyCell[T]
    var last = head
   
    def add(value: T): TypeList[T] = {
        if (head.isEmpty) {
            head = new ValueCell(value)
            last = head
        }
        else {
            last setNext new ValueCell(value)
            last = last.next
        }
        this
    }
   
    def remove(index: Int, node: ListCell[T]): ListCell[T] = {
        if (node.isEmpty)
            new EmptyCell[T]
        if (index == 0) {
            node.next
        }
        else {
            node.setNext(remove(index-1, node.next))
            node
        }
    }
   
    def get(index: Int, node: ListCell[T]): Option[T] = {
        if (node.isEmpty)
            None
        else
            if (index == 0)
                Some(node.value)
            else
                get(index-1, node.next)
    }   
}


Note que a implementação é praticamente a mesma, a única coisa diferente é o tipo do valor passado para guardar na lista. Repare que para quem usa a lista, basta adicionar um tipo no momento de criação da mesma, por isso em nosso teste mude apenas a linha que instancia uma nova lista, e rode o teste.

1
val list = new TypeList[String]


Crie um outro teste com um tipo de valor diferente e veja que funciona da mesma maneira que no Java.

Restrições de Tipos Genéricos


Nosso tipo T pode ser qualquer coisa. Existe em Scala uma sintaxe própria inclusive para inicializar uma varável de um tipo genérico, basta utilizar um ‘_‘. Dessa forma você está explicitando que sua variável pode ou não ter um valor do tipo genérico, afinal não tem como saber se o tipo será um primitivo ou não. Este é o caso em que estamos sujeito ao NullPointerException que citei no começo do post: para definir uma variável em Scala é necessário iniciá-la, e no caso de tipos genéricos, como não possível iniciá-los, as variáveis possuem valor nulo (‘_‘), logo geram código que pode lançar NullPointerException.

Com nosso tipo genérico podendo ser qualquer coisa, não conseguiríamos, por exemplo, ordenar nossa lista, afinal nem tudo é ordenável. A solução em Java é a mesma, mas a sintaxe em Scala me parece bem mais amigável. O que é necessário fazer, é dizer que o seu tipo obrigatoriamente extende de alguma classe determinada. No caso de querermos uma lista ordenada, basta obrigarmos o tipo passado extender de Comparable (no Java), ou Ordered (em Scala). Ordered extende Comparable, sobrescrevendo os operadores de comparação básico (>, <, >=, <=) e utilizando o método de comparação disponível em Comparable (compareTo).

Vamos mudar o parâmetro de nossa lista para obter tal comportamento. Para isto, basta mudar a assinatura da classe com seguinte código:

1
class TypeList[T <: Comparable[T]] {


Estou usando Comparable, pois não teremos erros de compilação usando String como parâmetro. Porém em Scala é possível dizer que um parâmetro poder ser convertido para o tipo definido na restrição. Esse tipo de restrição é chamado de View Bound e Scala já implementa a conversão implícita para os tipos primitivos e String, portanto se mudarmos nossa classe para:

1
class TypeList[T <% Ordered[T]] {


nosso código ainda compila, e nossos testes funcionam, o que é o mais importante :) .

Invariância e Covariância


Pensando em termos de orientação a objetos, se definirmos um lista TypeList[String], esta lista deve ser subtipo de TypeList[AnyRef]? Parece uma pergunta simples de se responder, mas as respostas tem suas implicações. Se a resposta é não, então estamos dizendo que quando criarmos uma lista de Strings, só faremos referência a essa lista sabendo que é do tipo String, e que portanto só adicionamos valores String na lista. Se a resposta é não, então estamos dizendo que ao criarmos um lista de Strings, podemos referenciá-la como uma lista de AnyRef e portanto conseguimos adicionar qualquer valor em nossa lista. O primeiro caso é dito invariante, e o segundo caso é dito Covariante.

Em Scala os tipos são por padrão sempre invariantes. Diferente do Java que é covariante.

Quando os tipos são covariantes, temos o problema de lidar com tipos diferentes dos esperados. Java resolve esse problema fazendo a verificação em tempo de execução, no momento da atribuição de um tipo. Em Scala o problema é resolvido de maneira estática impedindo o código de compilar. Ainda assim é possível estabelecer tipo covariantes em Scala. Para nossa lista, basta mudar a assinatura, com o operador +:

1
class TypeList[+T] {


Fazendo isso, seremos obrigados a mudar em todas as classes que usem T, por exemplo, nossas células.

Mas com isso surge um problema: como que o compilador irá saber tratar o tipo T de maneira que este possa ser de algum supertipo do mesmo? Para isso podemos definir nosso tipo T, como um limitante inferior. Basta usarmos a sintaxe simétrica a de restrições de limitantes superiores:

1
A >: T


Assim estamos dizendo que A é supertipo de T, e portanto podemos usá-lo em nossas funções sem que o compilador reclame.

Também podemos definir um range para nossas restrições combinando os operadores, por exemplo:

1
A >: B <: C


Objects


Scala não permite que usemos parâmetros em objects, por isso mesmo nossa célula vazia teve que definir um tipo para o parâmetro.

Para definirmos um object como super classe de uma classe que necessite de parâmetros, precisamos que a classe pai seja cocariante, e em nosso object, basta extendermos tal classe com o tipo Nothing. O tipo Nothing é subclasse de todos os tipos em Scala, portanto é o menor limitante inferior. Com isso conseguimos definir um object que extende uma classe que precisa de parâmetros.

Antes de falarmos de listas em Scala, ainda falta falarmos de tuplas e Functions. Veremos isso em um screencast que será divulgado em breve.

Espero que a série tenha andado bem até aqui, e que as informações que estou publicando sejam úteis a muitas pessoas. Lembrando que todos os tipos de comentários são bem vindos: críticas, dúvidas e sugestôes.

Por @Gust4v0_H4xx0r

Nov 5

Scala – Primeiros Passos

Escrito por DClick Team em 1, 4, 6, análise, AR, arte, auto, back, BI, blog, boolean, break, bug, busca, case, class, classe, classes, codec, código, comparação, comunidade, control, Curso, Cursos, demo, Desenvolvimento, Design, Documentação, Download, Eclipse, err, erro, error, eval, exemplo, Exemplos, Ferramenta, for, futuro, Geral, git, ide, IE, if, image, int, internet, Java, Javascript, loop, Mac, mg, novidade, O, on, oop, Orientação, Orientação a Objetos, Otimização, Outros, padrão, print, problema, problemas, programação, Projetos, pt, rest, RIA, Ria’s Geral, RoR, string, Sun, tag, TAT, Tema, Teste, Tutoriais, Tutorial, Twitter, UI, uint, Vários, XP, zend @ 11 5th, 2010 | via http://blog.dclick.com.br/pt/ | Sem comentários
DClick Team
? X
  • Bookmarks

Blinkbits BlinkLists BlogLines Blogmarks Buddymarks CiteULike Co.mments Del.icio.us Digg Diigo

Fark Feed Me Links Furl Google Linkagogo ma.gnolia Mister Wong Newsvine Propeller Rawsugar

Reddit Rojo Simpy Sphinn Spurl Squidoo StumbleUpon Tailrank Technorati Yahoo

More »

Twitter!


Aprendendo Scala

Estou começando uma série de posts sobre Scala para divulgar as minhas experências com a linguagem e suas aplicações. Vou tentar passar o funcionamento da linguagem e seus recursos, assim como também um pouco do paradigma de programação funcional, e tentar chegar em aplicações práticas no ambiente de desenvolvimento.

Existem alguns tutoriais disponíveis na internet bem interessantes mas que as vezes jogam muito conteúdo sem dar tempo para assimilar os conceitos. Nessa série de posts tentarei colocar os conceitos e ferramentas de Scala e linguagens funcionais de uma maneira natural, conforme eu mesmo for evoluindo na linguagem e também dando exemplos e exercícios para que você possa assimilar o que está sendo passado. Vou tentar explicar também conceitos mais teóricos do paradigma funcional, para que a linguagem que estamos falando seja a mesma.

Minha experiência com Scala é algo bem próximo do zero, por isso estou escrevendo esta série de posts com o intuito de me forçar a estudar a linguagem e também ajudar a divulgar uma das possíveis alternativas ao Java, afinal se trata de uma linguagem nova e que ainda não foi muito difundida na comunidade. Tratarei bem do básico nos primeiros posts com exemplos bem trivias apenas para ajudar na compreensão dos conceitos básicos. Também colocarei algumas bibliografias de onde se pode encontrar documentação sobre a linguagem.

Linguagens funcionais e Scala

Não é nova a ideia de se programar em um paradigma funcional. Linguagens funcionais existem a quanse tanto tempo quanto existe linguagens de programação. Com certeza na sua faculdade você viu, ou verá, linguagens como LISP, Scheme, Erlang, Clojure, etc… e atualmente que está ficando bem conhecida: Scala que roda em cima da JVM, a virtual machine do Java. Linguagens funcionais mudam o paradigma para focar em ‘funções’. Assim como em linguagens orientadas a objeto onde a unidade básica é uma intância de um objeto, em linguagens funcionais a unidade básica é uma função. Uma função nada mais é do que uma operação que recebe parâmetros, executa alguma ação e devolve um resultado. O funcionamento é muito parecido com o dos métodos em linguagens orientadas a objeto.

O interessante sobre Scala, é que a linguagem permite uma mescla do paradigma funcional com orientação a objeto. Existem conceitos de ambos implementados na linguagem e que fazem sentido quando aplicados em conjunto. Por exemplo, em scala existe o conceito de classe e de instâncias de classes, que são os objetos. Também existem funções que independem de uma classe para existirem. Se trata de um conceito muito poderoso, pois possibilita toda padronização e controle do design do sistema que as linguagens orientadas a objeto permitem, sem restringir o uso do dinamismo e abstração da linguagem funcional.

Mas claro que Scala e linguagens funcionais tem seus problemas. Por exemplo, não existe uma IDE sólida como o Eclipse ou o NetBeans para Scala. O que dificulta no momento de trabalhar com projetos muito grandes, com uma equipe com vários programadores. O dinamismo da linguagem também impede uma análise de código que por exemplo o PMD, ou o FindBugs disponibilizam no Java. Dessa forma, deveríamos garantir que as boas práticas e o design está sendo seguido com nossos testes unitários.

Chega de filosofar sobre a linguagem, vamos para a parte prática.

Instalando Scala

Para instalar o Scala basta acessar a página oficial de download neste link, e fazer o download de acordo com sua plataforma. Feito isso, descompacte o conteúdo em alguma pasta na sua máquina e adicione a pasta ‘bin‘ ao path do seu sistema operacional. Para se certificar que foi tudo instalado corretamente, abra um console e digite ‘scala‘, o terminal do scala deve abrir e aparecer uma tela como essa:

Agora que o terminal está sendo executado, digite ‘1 + 1‘ e repare na saída:

1
res0: Int = 2

É uma saída um tanto quanto confusa, mas que faz sentido no contexto do Scala. O que está acontecendo é que a unidade básica em Scala é uma função, portanto a operação + também é uma função, que foi executada no objeto ‘1‘, passando o parâmetro ‘1‘. Para se ter uma idéia melhor desse funcionamento, digite o seguinte no terminal:

1
scala> 1.+(1)

e aperte Enter. Repare na saída:

1
res1: Double = 2.0

Com exceção do tipo que era int e agora é Double, o funcionamento é exatamente o mesmo. Tal sintaxe já deve estar bem claro na cabeça da maioria dos programadores, mas a primeira sintaxe é só uma maneira difetente de se fazer a mesma chamada.

Conceitos básicos da linguagem

Vamos definir uma função para entender um pouco mais da sintaxe. Digite o seguinte:

1
2
scala> def a = 2 + 2
a: Int

Aqui estamos definindo uma função com o nome ‘a‘ que não recebe parâmetros, e devolve o resultado da soma ‘2 + 2‘. A palavra restrita return não é necessária, o compilador consegue inferir que a última expressão da função será o valor devolvido. Repare também que não precisamos definir o tipo que a função devolve, o qual também foi inferido pelo compilador. Portanto ao contrário do que possa parecer, Scala é uma linguagem tipada em tempo de compilação, portanto o seguinte trecho não compila:

1
2
3
4
5
6
7
8
9
scala> var b = “abc”
b: java.lang.String = abc

scala> b = a
<console>:7: error: type mismatch;
 found   : Int
 required: java.lang.String
       b = a
           ^

Repare que o compilador inferiu que o tipo da variável ‘b‘ é String (note que é o String do java), e que o tipo devolvido por ‘a‘ é Int, logo o código não compila. De certa forma esse comportamento é bom, pois garante uma maior integridade do código, sem que você tenha que programar para “deixar o compilador feliz“, ou seja, não existem tantas regras na escrita do código, porque muitas podem ser deduzidas a partir do contexto.

Um outro conceito de Scala é a diferença entre chamada por valor, e chamada por nome. Na chamada por valor é feita a evaluação da expressão assim que o código é executado, mesmo que não seja necessário usar o resultado da chamada. A vantagem é que evitamos executar outras vezes a expressão para obter o resultado, pois este já foi determinado. Na chamada por nome a evaluação da expressão ocorre apenas quando o resultado da chamada será usado, tendo um comportamento mais lazy. A desvantagem é a execução da expressão várias vezes para se obter o mesmo resultado, mas a vantagem é não fazer a execução quando não for necessário. Vamos ver um exemplo da diferença entre a chamada por valor e por nome. Volte no terminal e defina a seguinte função:

1
2
scala> def loop: Int = loop
loop: Int

Agora defina uma função que recebe dois inteiros e devolve o primeiro:

1
2
scala> def primeiro(x: Int, y: Int) = x
primeiro: (x: Int,y: Int)Int

Agora execute a chamada passando ‘loop‘ como segundo parâmetro e se prepare porque seu console irá travar na execução =):

1
2
scala> primeiro(0, loop)
_

Vamos fazer uma pequena modificação na definição de ‘primeiro‘ para tornar possível a execução de tal código:

1
2
scala> def primeiro (x: Int, y: => Int) = x
primeiro: (x: Int,y: => Int)Int

O que definimos agora foi que o segundo parâmetro de ‘primeiro‘ será uma função que devolve um Int. Assim seu resultado só será obtido quando for feita a chamada direta na expressão. Agora conseguimos fazer a chamada em nossa função:

1
2
scala> primeiro(0, loop)
res0: int = 0

Nossa função executou e finalizou sem problemas dessa vez, isso porque não foi necessário utilizar o segundo valor para obter o resultado. Essa é chamada por nome, e o primeiro exemplo é a chamada por valor.

Até agora vimos como invocar funções, como definir funções (def) e como definir variáveis (var). Vimos também o básico de inferência de tipo pelo compilador do scala e os primeiros conceitos da linguagem. Mas como eu havia dito, Scala também tem conceitos de orientação a objetos, portanto vamos definir nossa primeira classe em Scala:

1
2
scala> class AcumulaSoma { var acumulado = 0; def acumula(i: Int) = { acumulado = acumulado + i; acumulado } }
defined class AcumulaSoma

Lembre-se que não somos obrigados a definir o tipo devolvido pela função caso esteja explícito e também não precisamos da palavra reservada ‘return‘. O que fizemos foi definir uma classe que se chama ‘AcumulaSoma‘ que tem um atributo, que por padrão do Scala é de acesso privado, que se chama acumulado e que o compilador inferiu o tipo inteiro baseado no valor atribuído. Também definimos para a classe a função ‘acumula‘ que recebe um inteiro, guarda o valor acumulado até então da soma com o parâmetro passado e devolve tal valor. Vamos instanciar um objeto da nossa classe e fazer a chamada ao método:

1
2
scala> val ac = new AcumulaSoma
ac: AcumulaSoma = AcumulaSoma@cbbe37

Algumas diferenças com o Java (supondo que estamos mais acostumados com a sintaxe do Java) já podem ser notadas. Além da inferência do tipo de ‘ac‘ para ‘AcumulaSoma‘, criamos ‘ac‘ com a a palavra reservada ‘val‘, ou seja, estamos dizendo que diferente de ‘var‘ onde criamos uma variável, estamos criando um valor e estamos garantindo em tempo de compilação que este valor não pode ser alterado no código. No Java teríamos que usar a palavra ‘final‘ para obter o mesmo comportamento, em Scala temos que “satisfazer menos o compilador“. Também não foi necessário usar ‘()‘ para invocar o construtor de AcumulaSoma, e assim como no Java toda classe em Scala tem por padrão o construtor que não recebe parâmetros com acesso público. Continuando o exemplo:

1
2
3
4
5
scala> ac.acumula(2)
res0: Int = 2

scala> ac.acumula(1)
res1: Int = 3

Nada de novidade aqui, estamos invocando a função ‘acumula‘ no objeto ‘ac‘. Porém ‘acumula‘ é uma função que recebe um único parâmetro e devolve um valor. Dessa forma podemos executar a chamada da nossa função da outra forma que vimos anteriormente:

1
2
scala> ac acumula 4
res2: Int = 7

No Java conseguimos definir classes estáticas. Em Scala não existe exatamente o conceito de classes, atributos e parâmetros estáticos, porém existe um conceito mais bem definido: ‘object‘. Criamos um ‘object‘ igual criamos uma classe, com a diferença de que não é possível instanciarmos um object, afinal estamos definindo o próprio. Com essa diferença, estamos garantindo em tempo de compilação que o design do código, em que foi tomada a decisão de restringir a existência de apenas uma definição para determinada classe seja seguida. Em Java também é possível garantir tal critério em tempo de compilação, mas demanda a escrita de bem mais código e de uma compreensão um pouco maior do funcionamento e limitações da linguagem. Um exemplo de object:

1
2
3
4
5
scala> object Objeto { def valor = 5 }
defined module Objeto

scala> Objeto.valor
res3: Int 5

Existem os tipos primitivos básicos em Scala como Int, Long, Boolean, Float, Double, Short, Byte, Char e String, sendo que String é a String do ‘java.lang‘. Um fato interessante sobre Scala é que como a linguagem roda em cima da JVM, todas as bibliotecas disponíveis para Java também estão disponíveis para Scala.

O tipo que não vimos ainda é o ‘void‘. Em Scala não existe o conceito de void, toda função devolve um valor e quando não há um valor explícito a ser devolvido o compilador se encarrega de devolver um valor do tipo ‘Unit‘. Exemplo:

1
2
scala> def imprime = print(“Hello!”)
imprime: Unit

‘print’ é uma função que imprime um valor no terminal e não devolve valor, logo nossa função ‘imprime‘ também não devolve valor, portanto o tipo devolvido é ‘Unit‘, que também pode ser expressado/escrito como ‘()‘. A diferença básica entre void e Unit, é que Scala permite criar valores e variáveis do tipo Unit, e em Java por exemplo não é possível criar uma variável do tipo void. Também é possível analisar o valor devolvido por qualquer função mesmo que a função não devolva um valor definido e neste caso será um Unit. Um exemplo trivial de como usar este comportamento:

1
2
3
4
5
scala> def num = 9
num: Int

scala> def verificaUnit(f: => Any) = { f match { case x:Unit => print(“Eh Unit!”) case _ => print(“Nao eh Unit!”) } }
verificaUnit: (f: => Any)Unit

O tipo ‘Any‘ é análogo ao ‘Object‘ do Java, portanto pode ser qualquer valor, função ou objeto.

Nessa função estamos usando um tipo de switch case para obter o mesmo comportamento do ‘instanceof‘ em Java, afinal não existe tal operação em Scala. O que está acontecendo é que a função verificaUnit recebe uma função que não recebe argumentos e devolve um valor qualquer. A função ‘f‘ é então evaluada e o resultado da função é testado nos cases da operação ‘match‘. Caso seja do tipo Unit, imprimimos “Eh Unit!”, e no caso padrão imprimimos “Nao eh Unit!”. Repare que diferente do ‘switch‘, no ‘macth‘ não temos que chamar a operação ‘break‘ para não executar os outros casos. Para testar verificaUnit vamos fazer a chamada usando nossas outras duas funções que foram definidas:

1
2
3
4
scala> verificaUnit(num)
Nao eh Unit!
scala> verificaUnit(imprime)
Hello!Eh Unit!

Um exemplo mais prático

Vamos implementar um exemplo um pouco mais prático que calcula a raiz quadrada aproximada de um número. Para isso vamos usar o método de Newton de aproximações sucessivas. A idéia é bem simples, nada mais é do que uma busca binária entre os palpites que se aproximam cada vez mais da raiz quadrada do número passado. Vamos começar definindo uma função que diz se a raiz encontrada é boa o suficiente para ser o resultado:

1
2
3
4
5
scala> def abs (x: Double) = if (x > 0) x else -x
abs: (x: Double)Double

scala> def proximaOSuficiente(palpite: Double, x: Double) = abs((palpite * palpite) – x) < 0.0001
proximaOSuficiente: (palpite: Double,x: Double)Boolean

O bloco if é igual a sintaxe usada no Java, o mesmo vale para o else e o else if. Na segunda função estamos verificando se o número elevado ao quadrado é próximo o bastante do original. Agora vamos definir a função que faz um palpite melhor:

1
2
scala> def melhoraPalpite(palpite: Double, x: Double) = (palpite + x / palpite) / 2
melhoraPalpite: (palpite: Double,x: Double)Double

O que fizemos foi pegar um número para palpite que está entre o nosso palpite anterior e x dividido sobre o palpite anterior, onde x é o número que queremos obter a raiz quadrada. O método de Newton garante que para x >= 1 essa aproximação é sempre válida. Vamos agora a função que executa o método de Newton propriamente dito:

1
2
3
scala> def raizNewton(palpite: Double, x: Double): Double =
     | if (proximaOSuficiente(palpite, x)) palpite else raizNewton(melhoraPalpite(palpite, x), x)
raizNewton: (palpite: Double,x: Double)Double

Estamos calculando a raiz quadrada de modo recursivo até que o resultado seja bom o suficiente. Agora basta definir uma base para nossa função, para isso iremos pré-definir um valor para o palpite base, guardando a chamada nesse escopo em uma outra função:

1
2
scala> def raizQuadrada(x: Double) = raizNewton(1, x)
raizQuadrada: (x: Double)Double

Pronto, basta brincar com algumas chamadas para nossa função que calcula a raiz quadrada =).

1
2
scala> raizQuadrada(169)
res4: Double = 13.000000070110696

O resultado obtido não é muito preciso, mas também essa não é a melhor maneira de se calcular a raiz quadrada, inclusive para números muito grandes o algorítmo não funciona por restrições com a precisão do Double.

Algumas Considerações

A grande moda das linguagens funcionais está surgindo porque acreditasse que elas são o futuro para a programação concorrente e paralela, de que se o seu programa foi escrito em uma linguagem funcional você terá ganho o benefício da execução concorrente sem grandes esforços, bem, isso não é verdade. Linguagens funcionais como qualquer outro paradigma necessitam que o programa seja escrito de maneira que seu design seja voltado para execução concorrente ou paralela, a difenrença é que a sintaxe e as ferramentas disponíveis nas linguagens funcionais facilitam tal design.

Existem algumas técnicas de programação que surgiram com linguagens funcionais, como por exemplo Recursão em Cauda, que não entrarei no mérito nesse post mas que vale a pena pesquisar sobre o assunto. Tais técnicas facilitam a vida do compilador no momento em que for possível ser feita algum tipo de otimização.

Uma comparação que logo surge na cabeça dos programadores é: qual linguagem é melhor, Scala ou Java? A resposta é fácil… nenhuma. Cada linguagem tem um escopo e paradigma de atuação diferente, não tem como comparar ambas. O que talvez faça sentido comparar sejam fatores mais fora do domínio da linguagem, como por exemplo o tamanho da comunidade que utiliza efetivamente a linguagem, o tipo de suporte, a documentação disponível, as restrições de uso, mas em geral depende do caso de uso específico para o seu problema, e principalmente do gosto do programador.

Por enquanto é isso, em um próximo post tratarei de alguns outros tipos de funções e falarei um pouco mais sobre currying. Também darei exemplos de tipos diferentes de declarações de classes e objetos.

Referência: Scala By Example, Martin Odersky

Out 11

Falando de Desempenho

Escrito por Ebercom em 1, 4, api, AR, bar, BI, botão, comunicação, Curso, Cursos, dados, demo, desempenho, Desenvolvedor, Desenvolvimento, Desenvolvimento de Software, Dica, exemplo, for, Geral, IE, if, int, interface, Livro, Livros, NaN, O, on, Orientação a Objetos, problema, RIA, Ria’s Geral, servidor, Software, Tema, UI, Ved @ 10 11th, 2010 | via http://www.flexdev.com.br/home | Sem comentários
Ebercom
? X
  • Bookmarks

Blinkbits BlinkLists BlogLines Blogmarks Buddymarks CiteULike Co.mments Del.icio.us Digg Diigo

Fark Feed Me Links Furl Google Linkagogo ma.gnolia Mister Wong Newsvine Propeller Rawsugar

Reddit Rojo Simpy Sphinn Spurl Squidoo StumbleUpon Tailrank Technorati Yahoo

More »

Esses dias lendo o livro do Fowler (PoEAA), ele comenta um pouco sobre desempenho e como muitos dos termos de desempenho são usados de forma inconsistente. Para melhorar a comunicação de equipes de desenvolvimento de software resolvi publicar alguns termos e seus respectivos significados.

  1. Tempo de Resposta

    É a quantidade de tempo que o sistema leva para processar uma solicitação externa. Pode ser uma ação na interface com o usuário, como o pressionamento de um botão, ou uma chamada de API do servidor.

  2. Agilidade de Resposta

    A agilidade de resposta diz respeito ao quão rapidamente o sistema reconhece uma solicitação (em oposição ao tempo que leva para processá-la). Isso é importante em muitos sistemas porque os usuários podem ficar frustrados se um sistema demorar para responder a uma solicitação, ainda que seu tempo de resposta seja bom. Se o seu sistema esperar durante toda uma solicitação, então sua agilidade de resposta e o seu tempo de resposta são os mesmos. Entretanto se você indicar que recebeu a solicitação antes de completá-la, então sua agilidade de resposta é melhor.

  3. Latência

    É o tempo mínimo requerido para obter qualquer forma de resposta, mesmo se não houver nenhum trabalho a fazer. Se eu pedir a um programa para não fazer nada, então devo receber uma resposta quase instantânea se o programa rodar na minha máquina local. Entretanto, se o programa rodar em um computador remoto, pode demorar alguns segundos devido ao tempo gasto para que a solicitação e a resposta cheguem a seu destino através da conexão. Como desenvolvedor de aplicações, geralmente, nada posso fazer para melhorar a latência. A latência é o motivo pelo qual devemos minimizar chamadas remotas.

  4. Throughput

    É a quantidade de coisas que você pode fazer em uma dada quantidade de tempo. Se você estiver contabilizando o tempo gasto na cópia de um arquivo, o throughput poderia ser medido em bytes por segundo. Para aplicações corporativas, ume medida típica é o número de transações por segundo (tps), mas o problema é que isso depende da complexidade da sua transação.

    Nesta terminologia, desempenho pode significar tanto throughput quanto tempo de resposta – o que for mais importante para você. Às vezes, pode ser difícil falar sobre desempenho quando uma técnica melhora o throughput, mas piora o tempo de resposta. Assim é melhor usar o termo mais preciso. Da perspectiva de um usuário a agilidade de resposta em detrimento do tempo de resposta ou do throughput aumentará o desempenho.

  5. Carga

    A carga é uma medida da pressão a que o sistema está submetido, que poderia ser medida pelo número de usuários a ele conectados em um determinado instante de tempo. A carga é geralmente um contexto para alguma outra medida, como um tempo de resposta. Assim, você pode dizer que o tempo de resposta para alguma solicitação é de 0,5 segundo com 10 usuários e de 2 segundos com 20 usuários.

  6. Sensibilidade de carga

    É uma medida de como o tempo de resposta varia com a carga. Digamos que o sistema A tenha um tempo de resposta de 0,5 segundo para um número de usuários entre 10 e 20, e o sistema B tenha um tempo de resposta de 0,2 segundo para 10 usuários que aumenta para 2 segundos com 20 usuários. Neste caso o sistema A tem uma sensibilidade de carga menor do que o sistema B.

  7. Eficiência

    A eficiência é o desempenho dividido pelos recursos. Um sistema que obtenha 30 tps com duas CPUs é mais eficiente que uma que obtenha 40 tps com quatro CPUs idênticas.

  8. Capacidade

    A capacidade de um sistema é uma indicação do máximo throughput efetivo ou máxima carga efetiva. Este poderia ser um máximo absoluto ou um ponto a partir do qual o desempenho caia abaixo de um limite aceitável.

  9. Escalabilidade

    A escalabilidade é ume medida de como o acréscimo de recursos (normalmente hardware) afeta o desempenho. Um sistema escalável é aquele que lhe permite adicionar hardware e obter uma melhora de desempenho proporcional, como dobrar o número de servidores disponíveis para dobrar o throughput. A escalabilidade vertical, ou escalar para cima, significa adicionar mais poder a um único servidor (por exemplo, acrescentar memória). A escalabilidade horizontal, ou escalar para fora, significa adicionar mais servidores.

    O problema aqui é que as decisões de projeto não afetam todos esses fatores de desempenho de forma igual. Digamos que temos dois sistemas de software rodando em um servidor: a capacidade do Peixe-Espada é de 20 tps, enquanto a do Camelo é de 40 tps. Qual dos dois tem melhor desempenho? Qual é mais escalável? Não podemos responder a questão de escalabilidade com estes dados, e a única coisa que podemos dizer é que o Camelo é mais eficiente em um único servidor. Se adicionarmos outro servidor, percebemos que o Peixe-Espada agora trata 35 tps, e o camelo 50 tps. A capacidade do Camelo ainda é melhor, mas parece que o Peixe-Espada pode ter melhor escalabilidade. Se continuarmos adicionando servidores, descobriremos que o Peixe-Espada obtém 15 tps por servidor adicional e que o Camelo obtém 10. Com esses dados, podemos dizer que o Peixe-Espada tem uma melhor escalabilidade horizontal, ainda que o Camelo seja mais eficiente com menos de cinco servidores.

    Os projetistas muitas vezes fazem coisas complicadas que aumentam a capacidade de uma plataforma específica de hardware quando, em verdade, poderia ser mais barato comprar mais hardwares. Se o Camelo tem um custo maior do que o Peixe-Espada, e esse custo maior é equivalente a um par de servidores, então o Peixe-Espada acaba sendo mais barato, mesmo se você precisar de apenas 40 tps. Está na moda reclamar por ter que depender de hardware melhor para fazer o nosso software rodar apropriadamente. No entanto, adquirir hardware mais novo é com freqüência mais barato do que fazer o software rodar em sistemas menos poderosos. De forma semelhante, adicionar mais servidores é freqüentemente mais barato do que adicionar mais programadores – desde que o sistema seja escalável.

Set 24

Aprendendo PHP – parte 2

Escrito por Gabriel Versallini em 1, 4, 6, action, Air, AR, arte, Artigo, BI, blog, class, dados, Dica, Download, email, exemplo, Exemplos, for, Formulário, Formulários, html, IE, if, image, Java, Javascript, Livro, Livros, Mac, mg, mysql, NaN, Number, O, on, Orientação, Orientação a Objetos, padrão, Password, Pessoal, PHP, Plugin, produto, programação, pt, RIA, Ria’s Geral, servidor, social, string, TAT, UI, UX, web, XP @ 09 24th, 2010 | via http://www.versallini.com.br | Sem comentários
Gabriel Versallini
? X
  • Bookmarks

Blinkbits BlinkLists BlogLines Blogmarks Buddymarks CiteULike Co.mments Del.icio.us Digg Diigo

Fark Feed Me Links Furl Google Linkagogo ma.gnolia Mister Wong Newsvine Propeller Rawsugar

Reddit Rojo Simpy Sphinn Spurl Squidoo StumbleUpon Tailrank Technorati Yahoo

More »


Olá, pessoal!

No artigo anterior vimos um pouco do que é o PHP e de como a aplicação é executada. Neste artigo, veremos como transmitir, ou melhor, enviar dados ao arquivo.php através de um form (html). Mas antes de iniciarmos o estudo, gostaria de sugerir os livros a seguir para auxiliar na aprendizagem:

Pronto! Agora vamos ao trabalho. Primeiro vamos criar o arquivo contato.html para obter as informações. No nosso formulário poderemos o method GET ou POST. Vejamos a diferença entre eles:

O método GET transmite os dados primeiramente ao servidor web onde será armazenados temporariamente numa variável de contexto denominada QUERY_STRING.  Em seguida o arquivo indicado na diretiva action é acionado através da url e os dados transmitidos são exibidos após o a url utilizando o (?) para separar, por exemplo: http://www.versallini.com.br/mail.php?nome=Fulano. Já o método POST transmite os dados diretamente ao endereço que constar da diretiva action. Mas para isso é utilizado um script CGI para extrair os dados, normalmente o servidor PHP já vem com um script default (padrão).

Agora que já sabemos a diferença entre os métodos de envio vamos criar o nosso arquivo com o formulário:

?Download contato.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html>
<head>
<title>Aprendendo PHP - parte 2</title>
</head>
<body>
  <form action="confirmacao.php" method="POST">
    <fieldset>
    <legend>Inscrição:</legend>
     Nome: <input type="text" name="nome"><br>
     Email: <input type="text" name="email"><br>
     Senha: <input type="password" name="senha">
    </fieldset>
    <input type="submit" value="Enviar" />
  </form>
</body>
</html>

Veja como ficou:

Vamos criar agora o arquivo confirmacao.php. Para isso, precisamos entender que no php existe 3 comandos que permite a captura dados enviados por formulários, são eles: $_POST, $_GET e $_REQUEST. O $_REQUEST serve para capturar dados enviados através de qualquer um dos 2 métodos (GET ou POST), portanto é o melhor a ser usado no exemplo pois depois é possível mudar o método no formulário para GET sem precisar modificar o arquivo php. Vamos criá-lo:

?Download confirmacao.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
 
  // Declarando variáveis
  $Nome = $_REQUEST['nome'];
  $Email = $_REQUEST['email'];
  $Senha = $_REQUEST['senha'];
 
  // Exibindo os dados na tela
  echo "<h2>Confirmação de Dados</h2>";
  echo "Nome: $Nome<br />";
  echo "Email: $Email<br />";
  echo "Senha: $Senha<br />";
 
?>

Lembre-se de salvar os arquivos no diretório raiz do seu servidor web, no caso do EasyPHP é o www. Pronto! Vamos ver o resultado após o envio dos dados conforme a imagem anterior.

Fácil, né!? Neste exemplo utilizamos o método POST no formulário (html), experimente substituir por GET e veja a diferença na URL após o envio dos dados. Qualquer dúvida, comentem!

Um abraço

OBS.: Os exemplos são bem básicos devido a muitos colegas não terem nenhuma experiência com programação. Reforço a necessidade e importância da leitura de bons livros, juntamente com a prática. É isso!

Jul 28

Livro: Google Android

Escrito por Elvis Fernandes em 1, 2009, 4, 6, Android, api, aplicacao, app, AR, arte, auto, class, CRUD, cultura, Desenvolvimento, developer, Diversos, Documentação, DRE, err, erro, Excel, exemplo, Exemplos, Flex, Flex4, flexreport, fonte, for, git, Google, html, ide, IE, if, image, int, Java, lista, live, Livro, Livros, Mac, mg, NaN, O, on, Orientação, Orientação a Objetos, permalink, programação, pt, rails, rest, restfulx, RIA, Ria’s Geral, Sun, tag, Tema, UI, uint, XP @ 07 28th, 2010 | via http://www.elvis.eti.br | Sem comentários
Elvis Fernandes
? X
  • Bookmarks

Blinkbits BlinkLists BlogLines Blogmarks Buddymarks CiteULike Co.mments Del.icio.us Digg Diigo

Fark Feed Me Links Furl Google Linkagogo ma.gnolia Mister Wong Newsvine Propeller Rawsugar

Reddit Rojo Simpy Sphinn Spurl Squidoo StumbleUpon Tailrank Technorati Yahoo

More »

Este é o primeiro livro técnico que entra na minha lista de livros “completamente lidos”. Por se tratar de um livro técnico, não tem muito o que explicar sobre ele.

É uma fonte excelente de informações sobre programação para Android, o sistema operacional do Google para celulares. Explica muito bem os conceitos básicos para que o leitor possa iniciar rapidamente a programação para aparelhos com esse sistema, desde que tenha conhecimentos prévios de Java e Orientação a Objetos. Conhecimentos básicos sobre threads com Java também ajudam a entender melhor os exemplos.

Apesar de ser um livro longo (pouco mais de 600 páginas), o autor abriu mão de detalhes que muitas vezes interessam aos programadores – por exemplo, a forma como alguns registros são armazenados no dispositivo – em benefício da cobertura de diversos assuntos diferentes, que vão desde como funciona a estrutura da API do Android até a utilização do GPS ou da câmera do aparelho. Para encontrar esses detalhes que os programadores tanto gostamos (ainda estranho a silepse…), nada melhor que a documentação do sistema.

Posts relacionados

  • CRUD com o RestfulX – aplicação funcionandoCRUD with RestfulX – live application (2)
  • CRUD com o RestfulX: Parte 1/2 – RetrieveCRUD with RestfulX: Part 1/2 – Retrieve (5)
  • Erro “bad line length character” no Git (1)
  • Livro: Fernão de Magalhães (1)
  • FlexReport com o Flex4!FlexReport with Flex4 (3)
  • Livro: O homem que foi quinta-feira (1)
  • Livro: Ivanhoé (0)
  • Instalando sua aplicação Rails/RestfulX (e as gems) na DreamHost Installing your Rails/RestfulX app (and its gems) at Dreamhost (0)
  • Livro: As Aventuras de Tom Sawyer (1)
  • Livro: Histórias de Sherlock Holmes (0)

© Elvis for Elvis Fernandes, 2010. |
Permalink |
Nenhum comentário |
Adicione ao
del.icio.us


Tags: android, celular, Desenvolvimento, google, java, livro, programação

Jul 22

Curso Básico em Programação, aula 4 #soudev

Escrito por Ved em 1, 4, AR, BI, Curso, Gravação, ide, IE, O, on, Orientação a Objetos, procura, programação, Ria’s Geral, TAT, UI, Ved, window, windows @ 07 22nd, 2010 | via http://www.vedovelli.com.br | Sem comentários
Ved
? X
  • Bookmarks

Blinkbits BlinkLists BlogLines Blogmarks Buddymarks CiteULike Co.mments Del.icio.us Digg Diigo

Fark Feed Me Links Furl Google Linkagogo ma.gnolia Mister Wong Newsvine Propeller Rawsugar

Reddit Rojo Simpy Sphinn Spurl Squidoo StumbleUpon Tailrank Technorati Yahoo

More »

Infelizmente eu perdi a gravação desta aula. Depois de muito procurar, encontrei apenas o video (sem áudio), numa pasta temp nas profundezas do Windows. Bem, faça o seu melhor para acompanhar. =D Aula4 View more presentations from Fabio Vedovelli. Curso Básico de Programação – Aula 4 from Fabio Vedovelli on Vimeo.

Jul 18

Curso Básico em Programação, aula 5

Escrito por Ved em 1, BI, Curso, Download, ide, IE, O, on, Orientação a Objetos, programação, Ria’s Geral, TAT, Ved @ 07 18th, 2010 | via http://www.vedovelli.com.br | Sem comentários
Ved
? X
  • Bookmarks

Blinkbits BlinkLists BlogLines Blogmarks Buddymarks CiteULike Co.mments Del.icio.us Digg Diigo

Fark Feed Me Links Furl Google Linkagogo ma.gnolia Mister Wong Newsvine Propeller Rawsugar

Reddit Rojo Simpy Sphinn Spurl Squidoo StumbleUpon Tailrank Technorati Yahoo

More »

Aula5 View more presentations from Fabio Vedovelli. Curso Básico de Programação – Aula 5 from Fabio Vedovelli on Vimeo. Download dos slides em PDF

Jul 12

Criando uma aplicação WPF – Parte 1

Escrito por Alexandre Tadashi em .NET, 1, 4, 6, abas, app, AR, Arquitetura, arte, Artigo, Banco de Dados, blog, Blogs, botão, C#, camp, class, Class Library, classe, classes, comunidade, control, Controles, dados, demo, Desenvolvimento, Documentação, email, Entity Framework, exemplo, for, framework, Frameworks, git, Google, Hibernate, IE, if, image, Java, library, map, mg, Microsoft, O, on, Orientação, Orientação a Objetos, Outros, padrão, painel, processo, Projetos, pt, RIA, Ria’s Geral, server, servidor, silverlight, SQL Server, Sun, tag, TAT, Tema, template, tool, Tutoriais, Tutorial, UI, UX, Visual Studio, Visual Studio 2010, WPF, XP @ 07 12th, 2010 | via http://alexandretadashi.net/ | 1 comentário
Alexandre Tadashi
? X
  • Bookmarks

Blinkbits BlinkLists BlogLines Blogmarks Buddymarks CiteULike Co.mments Del.icio.us Digg Diigo

Fark Feed Me Links Furl Google Linkagogo ma.gnolia Mister Wong Newsvine Propeller Rawsugar

Reddit Rojo Simpy Sphinn Spurl Squidoo StumbleUpon Tailrank Technorati Yahoo

More »

Vou iniciar neste artigo o desenvolvimento de uma aplicação bem simples com WPF 4, o projeto consiste em um cadastro de contatos, onde o usuário poderá incluir, alterar ou deletar um contato, por questões didáticas, o exemplo terá somente 3 campos e 1 tabela, apesar de simples, estarei trabalhando em um sistema organizado em camadas, o projeto utilizará o Entity Framework 4 e será desenvolvido seguindo o padrão MVVM (Model View View-Model), que terá uma parte do tutorial somente para explicar o assunto conceitualmente e na prática.

Na primeira parte do mini tutorial nós veremos a camada de dados do projeto, nessa camada vamos programar a forma que o nosso sistema vai persistir os dados em uma base de dados, neste caso, o MS SQL Server Express 2008.

Atualmente existem diversas formas de realizar essa tarefa, o que dificulta um pouco saber qual a melhor, porem é comum fazer uso de frameworks para facilitar a persistência de dados, os frameworks O/R ajudam a manter o seu projeto padronizado, auxiliando muito em boas práticas quando temos sistemas orientados a objetos e banco de dados relacionais.

A escolha do melhor framework para um determinado projeto merece um estudo, sendo para a camada de persistência, seja para o padrão MVVM, Inversão de Controles, entre outros, uma das preocupações com o uso de frameworks é a descontinuação do mesmo por parte dos proprietários ou comunidade envolvida, mas por diversas vezes, o uso de frameworks é uma grande vantagem dependendo da situação.

Para a camada de persistência , dois frameworks tem se destacado, o nHibernate, projeto maduro, que teve sua origem no famoso framework Hibernate para Java e o Entity Framework 4, projeto da Microsoft e com vasta documentação disponível.

Recentemente iniciei meus estudos com o Entity Framework 4, e neste tutorial estarei utilizando o framework , o EF4 oferece o mapeamento objeto relacional (O/R), ou seja, permite mapear as tabelas do banco de dados como objetos, podemos criar o modelo de classes do projeto utilizando técnicas de orientação a objetos, como herança por exemplo, e neste momento não vamos nos preocupar em como o modelo de classes será registrado na base de dados.

Para iniciar, vamos criar uma Solution para guardar os projetos que farão parte dessa solução, abra o Visual Studio 2010, e clique em File – New -Project, em Installed Templates, clique em Other Project Types, e selecione Visual Studio Solutions e em seguida Blank Solution, ou seja, uma solução vazia, dê o nome de SolutionContato e clique em OK.

Clique na imagem para ampliar
Agora vamos adicionar um projeto que servirá como camada de dados, para isso clique com o botão direito do mouse em sua solution e Add – New Project, e em Visual C#, clique em Class Library e dê o nome de Contato.Data e clique em OK.
Clique na imagem para ampliar

Em seguida delete o arquivo Class.cs, pois não vamos utiliza-lo. Agora chegou o momento de criar o modelo de classes do entity framework 4, para isso , clique com o botão direito do mouse no projeto Contato.Data , e em Add - New Item.

Selecione a opção ADO.NET Entity Data Model e dê o nome de ModelContato.edmx e clique em Add para adicionar no projeto.

Agora aparecerá a tela Entity Data Model Wizard, nesta tela temos a opção de escolher entre “Generate from database” e “Empty Model”, a primeira opção permite você gerar o modelo de dados através de uma base de dados já existente, e a segunda opção, vai criar um modelo vazio, onde você poderá modelar as classes e posteriormente gerar as tabelas na base de dados, neste tutorial, vamos criar tudo do zero, selecione a opção , “Empty Model” e clique em Finish.

Clique na imagem para ampliar

No centro da tela temos o ModelContato.edmx, neste local vamos desenhar o modelo de entidades do projeto, como nosso exemplo é muito simples, selecione na janela Toolbox um elemento Entity e arraste e solte para dentro do ModelContato.edmx, note que uma classe já com uma propriedade Id foi visualmente inserida no ModelContato.edmx

Se um projeto tem mais entidades, você pode inserir da mesma forma e utilizar as associações entre as classes (Association) e Herança (Inheritance) disponíveis no painel Toolbox.

Em nosso projeto, vamos criar 3 propriedades para a entidade, o nome, telefone e email do contato, para isso , selecione a entidade, clique com o botão direito do mouse em Add – Scalar Property, e digite o nome da primeira propriedade “Nome”, repita o processo para adicionar as propriedades telefone e e-mail, altere também o nome da entidade, clicando em Entity1 e digitando Contato.

Chegou o momento de criar a base de dados do modelo criado, o entity framework e o Visual Studio 2010 facilitam muito esse trabalho, veja como é simples o processo , clique com o botão direito do mouse no ModelContato.edmx que está no centro da tela, e selecione Generate Database from Model…

Em Generate Database Wizard clique no botão New Connection para criar uma nova conexão com o SQL Server Express.

 

Clique na imagem para ampliar

Em Connection Properties, digite o nome do servidor em Server Name, e em Select or enter a database name, informe o nome de uma nova base de dados, neste exemplo, informe ContatoDB. Uma mensagem vai aparecer perguntando se deseja criar a base de dados, clique em Sim.

Clique na imagem para ampliar
Clique na imagem para ampliar

Pronto, deixe marcado a opção “Save entity connection setting in App.Config as” para que os dados da sua conexão sejam inseridos no arquivo App.Config e clique em Next.

Clique na imagem para ampliar

Um tela vai aparecer com todos os script para a criação das tabelas no SQL Server, clique em Finish, localize no Visual Studio 2010 o botão “Execute SQL” e clique para gerar a base de dados, se tudo ocorrer com sucesso, você receberá a mensagem Command(s) completed successfully.

Nesta primeira parte do tutorial vimos como adicionar o modelo de entidades utilizando o Entity Framework 4, segue a estrutura do projeto nesta etapa :

Jun 21

CRUD com Flex e Zend_AMF – Parte 2

Escrito por Daniel Schmitz em 1, 2009, 4, 6, Adobe, AMF, apache, app, AR, arte, Artigo, auto, Banco de Dados, bar, BI, botão, Botões, camp, class, classe, classes, código, Componente, components, configuração, control, Controls, CRUD, Curso, dados, DataGrid, demo, email, err, erro, error, event, events, Flex, Flex 4, for, Formulário, Formulários, function, Geral, IE, if, image, label, layout, library, mg, mudanças, MXML, mysql, O, on, Orientação, Orientação a Objetos, Password, PHP, problema, pt, RIA, Ria’s Geral, RoR, spark, string, tag, Teste, TextInput, Tutorial, UI, window, XML, zend @ 06 21st, 2010 | via http://flex.etc.br | Sem comentários
Daniel Schmitz
? X
  • Bookmarks

Blinkbits BlinkLists BlogLines Blogmarks Buddymarks CiteULike Co.mments Del.icio.us Digg Diigo

Fark Feed Me Links Furl Google Linkagogo ma.gnolia Mister Wong Newsvine Propeller Rawsugar

Reddit Rojo Simpy Sphinn Spurl Squidoo StumbleUpon Tailrank Technorati Yahoo

More »

Se você ainda não leu CRUD com Flex e Zend_AMF – Parte 1, leia agora :)

Agora que nossa conexão foi estabelecida, podemos começar a adicionar registros. Esta é a nossa primeira tarefa, e para isso precisamos criar um formulário de entrada de dados. Geralmente os formulários de entrada de dados são feitos em uma popup, e vamos seguir esta regra, ok?

Crie um novo MXML Component, chamado: PessoaForm.mxml, conforme a imagem a seguir:

image

O código inicial deste componente está a seguir:

<?xml version="1.0" encoding="utf-8"?>
<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
		   xmlns:s="library://ns.adobe.com/flex/spark"
		   xmlns:mx="library://ns.adobe.com/flex/mx"
		   width="300" height="150"
		   title="Pessoa"
		   close="{PopUpManager.removePopUp(this)}"
		   >
<s:layout>
	<s:VerticalLayout/>
</s:layout>

<fx:Declarations>
	<!-- Place non-visual elements
	(e.g., services, value objects) here -->
</fx:Declarations>

<fx:Script>
	<![CDATA[
		import mx.managers.PopUpManager;

		import spark.components.PopUpAnchor;
	]]>
</fx:Script>

<mx:Form width="100%" height="100%">
	<mx:FormItem label="Nome:" width="100%">
		<s:TextInput id="nome" width="100%"/>
	</mx:FormItem>
	<mx:FormItem label="Email:" width="100%">
		<s:TextInput id="email" width="100%"/>
	</mx:FormItem>
</mx:Form>

<s:controlBarContent>
	<s:HGroup horizontalAlign="right" width="100%">
		<s:Button id="btnOk" label="OK"/>
		<s:Button id="btnCancelar"
				  label="Cancelar"
				  click="{PopUpManager.removePopUp(this)}"/>
	</s:HGroup>
</s:controlBarContent>

</s:TitleWindow>

Neste código criamos um form com dois campos, mais os botões ok e cancelar. Até aqui nada de mais. O botão cancelar remove o popup, pois este TitleWindow será um popup.

Voltando à aplicação principal, temos que criar o botão que irá abrir este TitleWindow. Alterando o código da aplicação (Parte 1), temos:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
	   xmlns:s="library://ns.adobe.com/flex/spark"
	   xmlns:mx="library://ns.adobe.com/flex/mx"
	   minWidth="955" minHeight="600">

<fx:Declarations>
<mx:RemoteObject id="RemotePessoas"
				 destination="zend"
				 source="Pessoas">

	<mx:method name="TesteConexao"
			   result="OnTestConexaoOk(event)"/>

</mx:RemoteObject>
</fx:Declarations>

<fx:Script>
	<![CDATA[
	import forms.PessoaForm;

	import mx.controls.Alert;
	import mx.managers.PopUpManager;
	import mx.rpc.events.ResultEvent;
	public function OnTestConexaoOk(event:ResultEvent):void
	{
		Alert.show(event.result.toString());
	}
	]]>
</fx:Script>	

<s:Button label="Adicionar Pessoa" top="10" left="10">
<s:click>
	<![CDATA[
		var p:PessoaForm = new PessoaForm();
		PopUpManager.addPopUp(p,this,true);
		PopUpManager.centerPopUp(p);
	]]>
</s:click>
</s:Button>

</s:Application>

O botão “Adicionar Pessoa” da aplicação principal abre uma popup, exibindo o formulário abaixo:

Formulário Adicionar Pessoa

Agora podemos voltar ao código do formulário e adicionar a funcionalidade de “adicionar pessoa”. Para isso usamos o RemoteObject. O código do arquivo PessoaForm.mxml fica assim:

...
<fx:Declarations>

 <mx:RemoteObject id="pessoaRemote"
		 destination="zend"
		 source="Pessoas"
		 showBusyCursor="true"
		 >

	<mx:method name="Inserir"
	   result="OnInserir(event)"
	   fault="OnFault(event)"
	   />

  </mx:RemoteObject>

</fx:Declarations>

...

<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.managers.PopUpManager;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;

import spark.components.PopUpAnchor;

protected function OnInserir(event:ResultEvent):void
{
	PopUpManager.removePopUp(this);
}

protected function OnFault(event:FaultEvent):void
{
	Alert.show(event.message.toString(), "ERROR");
}

]]>
</fx:Script>

....

<s:Button id="btnOk" label="OK">
	<s:click>
	<![CDATA[
		pessoaRemote.Inserir(nome.text,email.text);
	]]<
	</s:click>
</s:Button>

As mudanças no código são relativas ao RemoteObject, que possui o método inserir, disparado pelo click do botão. O método inserir deve ser criado no arquivo pessoas.php, conforme o código a seguir:

<?php
class Pessoas
{
	var $db;

	function __construct()
	{
		$this->db = new Zend_Db_Adapter_Pdo_Mysql(array(
		'host'     => '127.0.0.1',
		'username' => 'root',
		'password' => '',
		'dbname'   => 'flexcrud'
		));
	}

	function TesteConexao()
	{
		return "OK";
	}

	function Inserir($nome,$email)
	{
		$data = array('nome'=>$nome,'email'=>$email);
		$this->db->insert('pessoas',$data);
		return $this->db->lastInsertId();
	}

}

Neste momento já podemos testar a aplicação. Caso dê algum erro, verifique o log de erros em c:wamplogsapache_error.log. Mas olhando o código do arquivo pessoas.php, podemos notar que ele tem um problema. Os parâmetros de conexão estão dentro da classe pessoas. Fiz isso de propósito, para mostrar que temos que ter uma visão crítica do nosso código, sempre que possível. Já imaginou termos 10 classes e cada uma delas tem as configurações do banco de dados? E se estas configurações mudarem?? Precisaremos alterar as 10 classes.. (eu acho que isso da justa causa hehe).

Para resolver o problema, podemos usar um pouco de orientação a objetos. Vamos criar uma classe chamada “Base”, que contém essa configuração, e fazer a classe Pessoas herdar de Base. Veja:

base.php:

<?php
class Base
{
	var $db;

	function __construct()
	{
		$this->db = new Zend_Db_Adapter_Pdo_Mysql(array(
		'host'     => '127.0.0.1',
		'username' => 'root',
		'password' => '',
		'dbname'   => 'flexcrud'
		));
	}
}

Agora a classe Pessoas fica assim:

<?php
include("base.php");

class Pessoas extends Base
{
	function __construct()
	{
		parent::__construct();
	}

	function TesteConexao()
	{
		return "OK";
	}

	function Inserir($nome,$email)
	{
		$data = array('nome'=>$nome,'email'=>$email);
		$this->db->insert('pessoas',$data);
		return $this->db->lastInsertId();
	}

}

Desta forma, conseguimos usar a variável $this->db em qualquer classe que herde da classe Base. No próximo artigo da série, iremos criar um datagrid para ver os dados que estão sendo inseridos. Aguardem!!

Jun 4

Pós Graduação em Métodos Ageis

Escrito por Daniel Lopes em 1, 3d, 6, análise, app, AR, Arquitetura, arte, bar, BI, busca, camp, class, css, css3, cultura, Curso, Cursos, Desenvolvimento, Desenvolvimento de Software, Desenvolvimento Web, Design, exemplo, Flex, for, Formação, Geral, html, html5, IE, if, int, internet, Java, Javascript, JQuery, Mercado, mg, NaN, O, on, Orientação, Orientação a Objetos, problema, processo, programação, Projetos, pt, rails, RIA, Ria’s Geral, Rich Internet Application, ruby, Ruby e Rails, ruby on rails, site, Software, Sun, Tecnologia, Tema, Teste, UI, usabilidade, web, XP @ 06 4th, 2010 | via http://blog.areacriacoes.com.br/ | Sem comentários
Daniel Lopes
? X
  • Bookmarks

Blinkbits BlinkLists BlogLines Blogmarks Buddymarks CiteULike Co.mments Del.icio.us Digg Diigo

Fark Feed Me Links Furl Google Linkagogo ma.gnolia Mister Wong Newsvine Propeller Rawsugar

Reddit Rojo Simpy Sphinn Spurl Squidoo StumbleUpon Tailrank Technorati Yahoo

More »

No começo deste ano recebi um convite um tanto inusitado mas bem interessante. Um convite do Edgard Davidson (da UNA) para ministrar a disciplina de desenvolvimento web em um novo curso de pós-graduação.

Com este post venho convidar as pessoas de BH e região para o curso de pós-graduação em engenharia de software centrada em métodos ágeis.

No começo deste ano recebi um convite um tanto inusitado mas bem interessante. Um convite do Edgard Davidson (da UNA) para ministrar a disciplina de desenvolvimento web em um novo curso de pós-graduação.

O problema

Sou bem crítico quanto a formação acadêmica. Ao contrário do que muitos falam eu sou sim a favor de graduação e acho que todos deveriam fazer. Principalmente quando estiverem entrando para o mercado, pois formação acadêmica contribui muito para que você tenha uma visão geral e abra o seu leque cultural sobre sua área de atuação e até como ser humano.

Apesar de pensar desta forma existe o outro fator que não obrigatoriamente pessoas graduadas serão bons profissionais (é bem comum vermos até o contrário). E devemos tentar imaginar o porque deste problema.

O meu ponto de vista é que os cursos são ruins (grade e carga teórica) e muitas vezes os professores também deixam a desejar (muitas vezes nunca tiveram experiência prática). Mas também não devemos tirar o foco dos alunos pois também carregam boa parte da culpa por saírem das faculdades com o conhecimento bem abaixo do aceitável.

Pensando desta forma, fiquei muito contente com a oportunidade de fazer alguma coisa para contribuir com uma solução para este problema. Este curso de pós-graduação possui uma grade e proposta bem diferente. Um curso com uma boa dosagem entre teoria e prática e principalmente uma grade disciplinas muito interessante.

Desenvolvimento web

A minha responsabilidade no curso será a disciplina de desenvolvimento web. Pretendo abordar desenvolvimento prático em Ruby e Ruby on Rails. Também vamos aprender conceitos fundamentais como por exemplo entender o protocolo HTTP (e como isso afeta o desenvolvimento web) além de ter uma visão geral das tendências atuais passando por assuntos como Javascript (em especial jQuery), HTML5 e CSS3.

Eu não posso responder por outras pessoas, mas prometo fazer o melhor possível nesta disciplina. E realmente vejo este curso como uma forma de criar grandes profissionais para o mercado mineiro, que ainda carece de pessoas com visões mais modernas no desenvolvimento de software.

Veja o texto oficial de divulgação do curso:

O curso de pós-graduação lato sensu em Engenharia de Software Centrada em Métodos Ágeis tem como objetivo principal especializar profissionais para o desenvolvimento de softwares de qualidade.

Este curso busca capacitar os participantes para uma visão abrangente e atualizada de engenharia de software e, em especial, capacitá-los em métodos ágeis focalizando nas tecnologias correntes para o desenvolvimento de software.

O curso contempla tópicos como métodos ágeis, programação orientada a objetos, padrões de projeto, engenharia de requisitos ágeis , usabilidade, arquitetura e teste de software bem com o desenvolvimento aplicações WEB e RIA (Rich Internet Application).

Durante o curso, os alunos exercitarão práticas ágeis integradas às outras disciplinas, proporcionando a transversalidade de conhecimento entre os conteúdos.

No final, o aluno estará capacitado a implantar, integrar e participar em equipes ágeis de desenvolvimento de software aplicando técnicas e tecnologias atuais de mercado.

Público-alvo

Profissionais de nível superior das áreas de Sistemas de Informação, Ciência da Computação, Análise e Desenvolvimento de Sistemas e Engenharia que atuam no mercado e que desejam se especializar no desenvolvimento de software com qualidade, flexibilidade e visando o máximo retorno sobre o investimento nos projetos de software, ampliando seus conhecimentos nas metodologias, tecnologias e processos que suportam o desenvolvimento ágil de software.

Estrutura curricular

  • Métodos ágeis de desenvolvimento de software
  • Modelagem Ágil de Software
  • Programação Orientação a Objetos
  • Padrões de Projeto
  • Engenharia de Requisitos Ágeis
  • Engenharia de Usabilidade
  • Arquitetura de software
  • Teste de Software
  • Desenvolvimento WEB
  • Desenvolvimento RIA
  • Laboratório de Engenharia de Software ágil
  • Métodos e Técnicas de Pesquisa

Dias e horários

O curso terá duração de 360h/a. Ocorrerá nos Campus Guajajaras (Sextas-feiras, das 19h25 às 22h55) e Barro Preto (Sábados, das 08h30 às 12h00 e das 13h00 às 16h30)

Coordenação

  • Edgard Davidson Costa Cardoso
  • E-mail: edgard.cardoso@prof.una.br
  • Veja a ementa completa

Investimento e mais informações

Confira aqui o valor do curso. Descontos especiais para matrículas antecipadas.

Para mais informações envie suas dúvidas para posgraduacao@una.br ou ligue para (31) 3235-7300. O site da universidade é www.una.br.

« Entradas anteriores | Entradas recentes »

ACERCA

O que é o RedeRIA ?

O redeRIA não é nada mais que um agregador de feed's que disponibiliza o conteudo de varios blogs e autores ao redor do mundo RIA, actualmente agregamos mais de 2791 entradas vindas de 53 blogs especializados em ria’s, pelo que só fica a ganhar em assinar o feed ou seguir a comunidade no twitter.

Se acha que o seu blog ou um blog de um amigo é interessante e util para os leitores o redeRIA, faça a sua submissão aqui.

Feed: assine já
Twitter: siga-nos

GOOGLE

Votação


Deveria o RedeRia agregar conteúdo em inglês?
Ver Resultados

AUTORES


Eduardo KrausAlexandre TadashiBindableCognitiva SoluçõesDaniel LopesDaniel SchmitzDanielPedrinhaDClick TeamEbercomEdgard DavidsonElvis FernandesErko BrideeFabiel PrestesFábio Batista da SilvaFabio da SilvaFabriccio BernardesFelipe BorellaFlavia MoreiraGabriel VersalliniGabriela T. PerryIgor MusardoJanderson CardosoJoão AugustoJose Carlos FielKelps SousaLeonardo FrançaLucas MarçalLuis MessiasLuiz TarabalMario JuniorMário SantosMauro MartinsPablo SouzaPedro ClaudioreneRia BrazilriaPTRicardo CerqueiraRobson FernandesRodrigo Pereira FragaSaintBrSamuelFacchinelloSergio SouzaSilva DeveloperStefan HorochovecTech CaffeTecinforThiago BuenoVedVinícius SandimWillian ManoXAML Cast

PUBLICIDADE








Powered by Wordpress & msdevstudio.com