Android/Patró observador amb exemples


Patró observador amb Exemples




Que es el patró observador?

modifica


Tota aplicació amb interfície gràfica conté una sèrie d'elements per interactuar entre la persona i el Sistema . Per exemple, quan
es fa click a un botó o s'escriu en un Edit Text el programa s'ha d'assabentar d'aquest fet..


Un mecanisme com es el Patró observador ens ajuda a resoldre aquesta qüestió.

És un patró de comportament, ja que determina com s’ha de realitzar l'intercanvi de missatges entre els diferents objectes per aconseguir realitzar una tasca . O també poden ser diferents elements i tot això es representa en termes diagrames UML's.


Aquest patró es sol veure en els frameworks d’interfícies gràfiques orientades a objectes, en què la forma de capturar els esdeveniments és subscriure “listeners” als objectes que poden generar esdeveniments com botons radio butons o fins i tot el teclat.

 

Model conceptual del patró observador

• Subjecte ( Subject): Coneix als seus observadors. j j ) Proporciona una interfície per agregar, eliminar, notificar, .. Observadors.

• Observador (Observer): Defineix el mètode que usa el subjecte per notificar canvis en el seu estat (update/notify).

• Subjecte Concret (ConcreteSubject): Manté l'estat d'interès per als observadors concrets i els notifica quan canvia el seu estat. No tenen perquè ser elements de la mateixa jerarquia.

• Observador Concret (ConcreteObserver): Manté una referència al subjecte concret i implementa la interfície d'actualització, és a dir, guarden la referència de l'objecte que observen, així en cas de ser notificats d'algun canvi, poden preguntar sobre aquest canvi.


 

principi de Hollywood

modifica

No ens truquis; ja et truquem nosaltres  


En la imatge de dalt ens mostra amb humor com funciona el principi de Hollywood. Això vol dir que ens hem d'esperar que hi hagi algú per nosaltres, i ells ja ens avisarà quan tingui alguna cosa per nosaltres quan ell dirà això va per vosaltres,


DIAGRAMA DE SEQÜÈNCIA

modifica

Quan passa l'event determinat aquest envia un missatge a l'activity perquè ella fagi les diferents respostes.

 

Aquí veiem el diagrama de seqüència del principi de Hollywood qui crida com es crida

Pseudocodi exemple de primera òpcio del principi de Holywood

modifica
 class Activity {
Button boto;
....
boto.avisam(this);
void clic() {.....}
}
 class Button{
Activity a;
void avisam(Activity a) {this.a=a;}
void clic() {a.clic();}

} 

Una llista de observadors

modifica

Aquí nomes veiem que hi ha un observable que rep la informació en un llista.
 

Exemples :

modifica

Java per processos

modifica

Ara passarem a veure un exemple molt smple amb Java sense fer servir listeners, per processos . Podem dir que això que es un procces es lo mateix que uin listener.

package obs;
import java.util.Observable; //Observable és aquí
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class EventSource extends Observable implements Runnable 
{
    public void run()
    {
        try
        {   
             //Fem un Reader per agafar el text que s'escriu dintre de la pantalla 
            final InputStreamReader isr = new InputStreamReader( System.in );
            final BufferedReader br = new BufferedReader( isr );
            while( true )
            {

                final String response = br.readLine();
                setChanged();
                notifyObservers( response );
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}

Aquí veiem una classe java que espera que escrivim una línia per passar-la a tothom qui l'estigui observant.


 /* Nom del fitxer: ResponseHandler.java */

package obs;

import java.util.Observable;
import java.util.Observer; /* this is Event Handler */

public class ResponseHandler implements Observer
{
    private String resp;
    public void update (Observable obj, Object arg)
    {
        if (arg instanceof String)
        {
            resp = (String) arg;
            System.out.println("\nResposta rebuda: "+ resp );
        }
    }
}

Aquí veiem que quan li arriba on objecte arg que és un string es treu un missatge per pantalla.

/* Nom del fitxer: myapp.java */
/* És el programa principal */

package obs;

public class MyApp
{
    public static void main(String args[])
    {            
        System.out.println("Entra text >");

        // crea un codi d'esdeveniment - llegeix des de stdin
        final EventSource evSrc = new EventSource();

        // crea un observer
        final ResponseHandler respHandler = new ResponseHandler();

        // subscriu l'observer al codi d'esdeveniment
        evSrc.addObserver( respHandler );

        // comença el thread d'esdeveniment
        Thread thread = new Thread(evSrc);
        thread.start();
    }
}




Java amb un botó i una label

modifica

Botó que espera

 

El botó té un listeners perquè quan es clica posa a la Label Botó clicat.

 



package listeners;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

/**
 *
 * @author Jaume
 */
public class Listeners {
        private static JFrame pp;
        private static  JButton bb;
        private static JLabel ll; 
        
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        
        ll= new JLabel();
        ll.setSize(20, 10);
        
         pp =new JFrame ();
        bb = new JButton();
        bb.setText("clicam");
        bb.setSize(100 , 100 );
        pp.add(bb);
       pp.add(ll);
       
        bb.addActionListener(new  ActionListener() {
             @Override
             public void actionPerformed(ActionEvent e) {
                 ll.setText(" botó clicat" );
             }
         });
        pp.setSize(300, 300);
        
        pp.setVisible(true);
        
        
        
        
    }
    
}

Andriod + java

modifica

 

Codi per fer la interfície

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MkM"
    android:weightSum="1"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/com"
        android:id="@+id/txtinixial"
        android:layout_weight="0.05" />

    <EditText
    android:layout_width="178dp"
    android:layout_height="wrap_content"
    android:id="@+id/editText"
    android:layout_weight="0.07" />

    <RadioGroup
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="0.05"
        android:id="@+id/radiogrup"
        android:baselineAligned="true">

        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/km"
            android:id="@+id/rdbKM"
            android:layout_weight="1"
            android:checked="false" />

        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/Milles"
            android:id="@+id/Milles"
            android:layout_weight="1" />

    </RadioGroup>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/sss"
        android:id="@+id/convertir"
        android:layout_weight="0.09"
        android:layout_gravity="center_horizontal|bottom"
        />

</LinearLayout>


Podem veure que aquí el listener del botó enlloc de definir-lo amb l'atribut onClick del button es fa en codi java.

Ara anem a agafar les funcions en el codi java:

package com.jaume.layouts;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;

public class MkM extends Activity {


    private EditText text;
    private RadioButton milles;
    private RadioButton km;
    private Button but;
    public static final double COL = 1.609344;


    private  void ini(  ) {

        text = (EditText) findViewById( R.id.editText );
        milles =(RadioButton) findViewById(R.id.Milles);
        km = (RadioButton) findViewById(R.id.rdbKM);
        but= (Button) findViewById(R.id.convertir);

        but.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                convertir(v);
            }
        });
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mk_m);

        ini();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_mk_m, menu);
        return true;
    }

    public void convertir (View v){

        String con;
        boolean mil;
        boolean kme;
        float oo;
        con= text.getText().toString();
        oo= Float.parseFloat(con);
        mil= milles.isChecked();
        kme=km.isChecked();
        if (milles.isChecked()){
             text.setText(String.valueOf(oo*COL));
            milles.setChecked(false);
            km.setChecked(true);
        } else {
            text.setText(String.valueOf(oo/COL));
            milles.setChecked(true);
            km.setChecked(false);

        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}