Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Najbolji nacin za Handle-ovanje poruka IRC protokola

[es] :: Java :: Najbolji nacin za Handle-ovanje poruka IRC protokola

[ Pregleda: 1405 | Odgovora: 3 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Man-Wolf
Mihailo Joksimovic
Beograd

Član broj: 17016
Poruke: 873
*.adsl.beotel.net.



+13 Profil

icon Najbolji nacin za Handle-ovanje poruka IRC protokola24.03.2010. u 10:32 - pre 170 meseci
Pozdrav kolege,

Nazalost, cini mi se da naslov teme nije najbolji, ali zaista nisam znao kako drugacije da nazovem istu, tako da, izvinjavam se unapred

Elem, imam sledeci problem, tj. dilemu, kako god - Radim seminarski iz Jave i odlucio sam da to bude Chat aplikacija za IRC. Za sada je sve ok, s tim sto imam jedan "problemcic" - handle-ovanje poruka koje mi salje IRC. O cemu se konkretno radi:

Poruke koje salje IRC server su sledeceg tipa:

Citat:

:<posiljalac> <TipPoruke> <detalji poruke i/ili sama poruka .....>


Konkretan primer:

Citat:

:irc.us.mibbit.net 376 Mixaj :End of /MOTD command.


Bitan je ovaj boldovan deo, tj. tip poruke/informacije i tu se javlja konkretan problem - obrada/handle-ovanje iste. Znaci, trenutno to radi na sledeci nacin:

Code (java):

// Get the ERROR reply numeric (2nd fragment)
        int error_reply = Integer.valueOf(getMessageFragment(1));

        switch (error_reply) {

            case 401:
                process_401();
                break;
            case 403:
                process_403();
                break;
 


Znaci, kroz SWITCH provlacim taj numericki deo poruke i na osnovu tipa poruke, pozivam metodu koja ce da procesira tu poruku. To je sve ok i ok radi, ali, nesto mi se cini da ovo nije bas najbolji nacin za handle-ovanje poruka. Trenutno sam na nekom "Advanced Hello World" nivou programiranja u Javi, tako da nisam bas najbolje upoznat sa mogucnostima iste :-( Elem, posto dolazim iz sveta PHP-a, prva ideja mi je bila da na osnovu tipa greske, pozivam metodu sa istim imenom, tj. konkretno, nesto ovog tipa (pseudo kod):

Code:

- Proveri da li metoda "process_TIP-PORUKE" postoji
  - Ako postoji - pokreni je
  - Ako ne - uradi nesto pametno (ili ne radi nista, nije ni bitno)


Ovo bi se u PHP-u vrlo jednostavno uradilo, ali nazalost, koliko sam uspeo da izguglam, u Javi bas nije tako jednostavno. Jedino sto sam nasao jeste "Java Reflection", ali nakon dosta ne uspelih pokusaja sam shvatio da nema vajde od toga (sa mojim trenutnim nivoom znanja iste :-().

Tako da, moje konkretno pitanje jeste - da li postoji neki elegantniji nacin za obradu ovih poruka, ili sam osudjen da pravim switch sa 150 case-ova

Nadam se da nisam previse konfuzno postavio pitanje

Hvala unapred !

Pozz
 
Odgovor na temu

reg
java,java,java
bgd

Član broj: 249663
Poruke: 30
*.dynamic.sbb.rs.



Profil

icon Re: Najbolji nacin za Handle-ovanje poruka IRC protokola24.03.2010. u 15:20 - pre 170 meseci
Pre konkretnog odgovora jedno opste resenje koje se koristi
za razna mapiranja u Javi.

Dakle kreiras klasu koja ce da sluzi kao maper
izmedju onoga sto ti stigne u runtime-u iz app. logike (npr number poruke 400)
i svih tvojih predefinisanih vrednosti (ovde su to imena procesa)


Code:
public class MessageRegister {
    
    
    private Hashtable<Integer, String> messages; 
    
     public MessageRegister() {
        messages = new Hashtable<Integer, String>();
        
        addMessage(400, "process_400()"); //401 process_401();
        addMessage(401, "process_401");  
        /*svaka nova metoda se dodaje ovde rucno*/
    }
    
     public void addMessage(Integer number, String name){
         messages.put(number, name);
     }
     
     
     public String getMessage(Integer number ){
         return messages.get(number);
     }
     
     
     public static void main(String[] args) {
        MessageRegister mr = new MessageRegister();
        
        /*poziv iz app logike*/
        System.out.println( mr.getMessage(400) ); //ukoliko se pozove sa nepostojecim kljucem vratice null
    }
}


KONKRETNO RESENJE:

Postoji Genericka poruka koja je apstaktna klasa.
Svaka specificna poruka (400, 401...) mora da je implemetira.
Moras da ih napises oniko koliko je case-ova kako si ih ti nazvao
ali svaka mora da implementira abtract methodu u kojoj je njena specificna app logika.

Postoji klasa mapa takodje mapa kao ona gore prva koju sam naveo kao primer.
U njenom konstruktoru svaki put kada kreiras specificnu poruku koja impl. aps genericku poruku
dodas vrednost onoga sto ce se mapirati iz app logike i tvoje specificne poruke.


Code:
import java.util.Hashtable;

public class MessageRegisterMethodsAsClasses {

    private Hashtable<Integer, MessageGenericType> messages;
    
    public MessageRegisterMethodsAsClasses() {
        messages = new Hashtable<Integer, MessageGenericType>();
        
        /*add specific type*/
        addMessage(400, new MessageSend(MethodNames.SEND)); // npr komanda za neko slanje poruke
        addMessage(401, new MessageBlock(MethodNames.BLOCK)); //kod tebe je ovo NPR 401 process_401();
        
    }
    
    public void addMessage (Integer number, MessageGenericType messageType){
        messages.put(number, messageType);        
    }
    
    public MessageGenericType getMessageType(Integer key){
        return messages.get(key);
    }
    
    
    
    public static void main(String[] args) {
        
        MessageRegisterMethodsAsClasses m = new MessageRegisterMethodsAsClasses();
        
        /*ovo je poziv iz iz app logike koji ti kaze da se radi o poruci tipa 400*/
        MessageGenericType mgt =  m.getMessageType(400);
        mgt.performAction(); //a ovde je sada izvrsavas - nema case vise
        
    }
    
}






Code:

public abstract class MessageGenericType {

    private MethodNames messageName;
    
    public MessageGenericType(MethodNames name) {
        this.messageName = name;
    }
    
    public abstract void performAction();
}



Code:

public enum MethodNames {

    SEND,
    BLOCK,
    STOP
    
}



Code:

public class MessageSend extends MessageGenericType {


    public MessageSend(MethodNames name) {
        super(name);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void performAction() {
        
        System.out.println("i'm sending message..");
        
    }

    
}



Pitanje za tebe: Da li zaista imas 150 caseova??
Mozes li da ih svedes na manji broj da ne bi pisao previse
specificnih klasa?

Takodje ti preporucujem da proucis "enum"
Ja ovde nisam morao da ga koristim za imena klasa
ali bi ti svakako trebalo da ga koristis za statuse poruka (400,401)
Nikada zbog sigurnosti tipova podataka ne zelis da neko moze da pozove
npr (int messageCode = 8454802125) jer ce to tvoj kod koji radi sa int-egerima progutati
a ako ih sve stavis u "enum" i predefinises,
onda ces prilikom poziva morati da pitas predefinisalni enum za vrednost
a ne da postavis bilo koju. Ovo ostavljam tebi.

pozz!


 
Odgovor na temu

Man-Wolf
Mihailo Joksimovic
Beograd

Član broj: 17016
Poruke: 873
*.adsl.beotel.net.



+13 Profil

icon Re: Najbolji nacin za Handle-ovanje poruka IRC protokola25.03.2010. u 09:58 - pre 170 meseci
Prvo, hteo bih iskreno da ti se zahvalim na ovako iscrpnom odgovoru :-)

Moram priznati da si me sad ubio u pojam totalno hehe. Verovao ti ili ne, ja sam na pocetku, upravo bio napravio HashMap-u u kojoj je key bila poruka (npr. 401), a value je bilo ime metode koja je trebala da se poziva :-) Ideja je bila sledeca -

1. Parsiram primljenu poruku
2. Pogledam da li primljeni NUMERIC (npr 401) postoji u HashMap-i
3. Ako postoji, uzmi value i pozovi metodu sa tim imenom

Nazalost, posto nisam uspeo da pozivam metode na osnovu imena (kao sto sam pomenuo u prethodnoj poruci - nisam uspeo da se snadjem sa Java Reflection-om), odustao sam od toga i resio da NUMERIC poruke provlacim kroz switch - case, case,.... Nazalost, znao sam da je to verovatno najgore moguce resenje, ali, nisam mogao da nadjem bolje. Btw, HashMap jos uvek postoji, samo sto sam umesto imena metoda ostavio samo Stringove koji "blize opisuju poruku" (potajno sam verovao da cu ipak naci neku primenu te HashMap-e :-D). Evo kako to izgleda:


Code (java):

// ERR_NOSUCHNICK
error_reply_numerics.put(401, "ERR_NOSUCHNICK");
// ERR_NOSUCHCHANNEL
error_reply_numerics.put(403, "ERR_NOSUCHCHANNEL");
// ERR_TOOMANYCHANNELS
error_reply_numerics.put(405, "ERR_TOOMANYCHANNELS");
// ERR_UNKNOWNCOMMAND
error_reply_numerics.put(421, "ERR_UNKNOWNCOMMAND");
 


Nazalost, nije mi ni u jednom trenutku palo na pamet da u HashMap-u ubacujem objekte poruka (sve vreme sam bio nosen idejom da smestam imena metoda :-().

U svakom slucaju, puno ti hvala na ideji, definitivno cu da je primenim.

Samo, jedna stvar mi nije bas najjasnija:

Citat:

Takodje ti preporucujem da proucis "enum"
Ja ovde nisam morao da ga koristim za imena klasa
ali bi ti svakako trebalo da ga koristis za statuse poruka (400,401)
Nikada zbog sigurnosti tipova podataka ne zelis da neko moze da pozove
npr (int messageCode = 8454802125) jer ce to tvoj kod koji radi sa int-egerima progutati
a ako ih sve stavis u "enum" i predefinises,
onda ces prilikom poziva morati da pitas predefinisalni enum za vrednost
a ne da postavis bilo koju. Ovo ostavljam tebi.


Znam kako se koriste enum-i, ali, nije mi bas najjasnije kako bih mogao da ih primenim za statuse poruka ? :-)

Hvala ti jos jednom !

EDIT:

Citat:

Pitanje za tebe: Da li zaista imas 150 caseova??
Mozes li da ih svedes na manji broj da ne bi pisao previse
specificnih klasa?


Mislim da ih nema bas 150, ali, generalno - ima ih dosta (http://irchelp.org/irchelp/rfc/chapter6.html). Naravno, nisam planirao da obradjujem sve poruke (usled nedostatka vremena, treba do sutra da zavrsim aplikaciju), ali, generalno, zanimalo me je neko "pametno" i generalno resenje :-)
 
Odgovor na temu

reg
java,java,java
bgd

Član broj: 249663
Poruke: 30
*.dynamic.sbb.rs.



Profil

icon Re: Najbolji nacin za Handle-ovanje poruka IRC protokola25.03.2010. u 17:18 - pre 170 meseci
Nema na cemu, ovo sto radis je jako tipican problem i trebace ti za ubuduce,
zato je najbolje da sada celu stvar odradis kako treba.

Celu pricu oko korisnosti enuma imas ovde:
enum in java

Razmisli da li zelis da radis sa obicnim konstantama za statuse poruka ili mozda nesto ovako:

Primer:


Code:

public class EnumIRC {

    private REPLY reply;
    
    enum REPLY {

        
        ERR_NOSUCHNICK (401),
        ERR_NOSUCHSERVER (402),
        ERR_NOSUCHCHANNEL(403);
        /*ovde dodajes sve 6.1 Error Replies.*/
        
        /*takodje ako je potrebno mozes da dodas i OPIS kao drugi clan...:
        
        ERR_NOSUCHNICK(401,"Used to indicate the nickname parameter supplied to a command is currently unused."),
        Duzan si naravano da definises drugi clan isto kao i "code" clan i da ga stavis u constructor i kreiras getter za njega
         **/

        private final int code;   // in kilograms

        private REPLY(int c ) {
            this.code = c;
        }

        int code() { return code; }

    }//enum     


    
    
    public static void main(String[] args) {
    
        EnumIRC en = new EnumIRC();
            
        /*status stigao negde iz app logike*/
        int status = 403;
        
        /*ispitivanje vrednosti*/
        if (status == REPLY.ERR_NOSUCHCHANNEL.code)
        System.out.println("true");
        
        
        /*za rad sa rangeom vrednosti*/
        for (REPLY rep : EnumSet.range(REPLY.ERR_NOSUCHNICK , REPLY.ERR_NOSUCHSERVER)){
            System.out.println(rep.code());
            System.out.println("zajednicki kod - npr poziv iste metode da nesto uradi");
        }
            

        
    }

}


Na tebi je da to posle koristis i u maperu i na drugim mestima.

Mnogo je lakse ne pamtiti sta koji status znaci i raditi sa njegovim opisom koji je day u enumu
i uz sve to obezbediti type safety svakog statusa
nego raditi sa obicnim konstantama.
Kao sto vidis ima jos korisnih metoda koje ti mogu pomoci u radu - "range" i sl.

pozz


 
Odgovor na temu

[es] :: Java :: Najbolji nacin za Handle-ovanje poruka IRC protokola

[ Pregleda: 1405 | Odgovora: 3 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.