"Commander" v Jave

"Commander" v Jave

Příspěvekod Gelidus » 10 srpen 2012 22:29:14

Zdravím, nejaký čas som venoval C# a povráva sa, že sharp je kópia javy, tak som sa to rozhodol dneska skúsiť. Napadlo ma spraviť jednoduchý systém na commandy. Nechcem počuť aké je to dobré (aj keď to určite počuť nebudem :D) ale práve naopak, čo by sa dalo spraviť inak-lepšie. Tak tu to máme :

CommandTable.java
Kód: Vybrat vše
import java.util.*;

/**
 *
 * @author Gelidus
 */
public final class CommandTable {
   
    /**
     * Container for all table commands
     */
    public Map<String, Command> CommandMap;
   
    /**
     * Constructor used to fill Command table
     */
    public CommandTable(Command[] commands) {
        this();
        for(Command command : commands) {
            this.RegisterCommand(command);
        }
    }
   
    /**
     * Default constructor for CommandTable
     */
    public CommandTable() {
        this.CommandMap = new HashMap<>();
    }
   
    /**
     * Main function for Command Table, call every time you want to search for a
     * command in table
     */
    public boolean Call(String argument) {
        String[] args = argument.split(" ");
       
        if(this.CommandMap.containsKey(args[0])) {
            return this.CommandMap.get(args[0]).Call(RemoveFirstString(args));
        }
        System.out.println("Command not recognized");
        return false;
    }
   
    /**
     * Function used to register new command for table
     */
    public boolean RegisterCommand(Command command) {
        if(!this.CommandMap.containsKey(command.Trigger)) {
            this.CommandMap.put(command.Trigger, command);
            return true;
        }
        return false;
    }
    /**
     * Function used to unregister existing command for table
     */
    public boolean UnregisterCommand(Command command) {
        if(!this.CommandMap.containsKey(command.Trigger)) {
            this.CommandMap.remove(command.Trigger);
            return true;
        }
        return false;
    }
   
    public static String[] RemoveFirstString(String[] args) {
        String[] ret = new String[args.length-1];
        for(int i = 1; i < args.length; i++) {
            ret[i-1] = args[i];
        }
        return ret;
    }
}


Command.java
Kód: Vybrat vše
/**
 *
 * @author Gelidus
 */
public class Command {
   
    public String Trigger;
   
    public CommandTable SubCommandTable;
   
    /**
     * Constructor for Command class
     */
    public Command(String trigger) {
        this.SubCommandTable = new CommandTable();
        this.Trigger = trigger;
    }
   
    /**
     * Method used by CommandTable when Command is triggered
     */
    public final boolean Call(String[] args) {
        if(this.SubCommandTable.CommandMap.isEmpty() || args.length == 0) {
            OnCall(args);
            return true;
        }
       
        if(this.SubCommandTable.CommandMap.containsKey(args[0])) {
            return this.SubCommandTable.CommandMap.get(args[0]).Call(CommandTable.RemoveFirstString(args));
        }
       
        OnCall(args);
        return true;
    }
   
    /**
     * This should be override
     */
    boolean OnCall(String[] args) {
        return true;
    }
}


Tak, ako bude teda vyzerať taký "example" ?

Kód: Vybrat vše
/**
 *
 * @author Gelidus
 */
public class ExampleCommand extends Command {
    public ExampleCommand(String Trigger) {
        super(Trigger);
       
        //Registrujeme sub-command
        this.SubCommandTable.RegisterCommand(new ExampleSubCommand("druhy"));
    }
   
    @Override
    boolean OnCall(String[] args) {
        System.out.println("Normalny command");
        return true;
    }
   
    //vytvorenie triedy pre ExampleCommand ktorej objekt zas vytvoríme v constructore ExampleCommand
    public class ExampleSubCommand extends Command {
        public ExampleSubCommand(String Trigger) {
            super(Trigger);
        }
   
        @Override
        boolean OnCall(String[] args) {
            System.out.println("Subcommand");
            return true;
        }
    }
}


Ako to teraz všetko využiť?

Kód: Vybrat vše
public static void main(String[] args) {
        CommandTable table = new CommandTable();
        table.RegisterCommand(new ExampleCommand("prvy"));
       
        InputStreamReader inputStream = new InputStreamReader(System.in);
        BufferedReader reader = new BufferedReader(inputStream);
       
        System.out.print("Zadaj Command : ");
        String c = "";
        try {
            c = reader.readLine();
        }
        catch(IOException ex) {
        }
       
        table.Call(c);
    }


Vstupy a výstupy

Na základe tohoto kódu sme vytvorili CommandTable s jedným commandom. Tento náš Command má ešte svoj subcommand.

Ak teda vložíme do konzoli "prvy", dostaneme výstup "Normalny command"

Ak vložíme "prvy druhy", dotaneme výstup "Subcommand"

Ak vložíme "prvy bla", dostaneme ten istý výstup ako pri vložení "prvy", pretože subcommand nebol nájdený, argumenty spadajú pod hlavný command

Ak vložíme "prvy druhy treti", dostaneme výstup "Subcommand", pretože ku commandu "druhy" neexistuje žiadny ďalší subcommand s triggerom "treti", "treti" teda spadá ako argument pod tento command.



Pokiaľ by neboli niektoré časti kódu zrozumitelné, napíšte sem a ja to dopíšem :)

Edit : ešte k Jave a C#, často som mal pri písaní tohoto taký pocit, že v C# by som to napísal o dosť ľahšie, no možno to je aj tým časom.

Gelidus :innocent:

P.S. Wolf nedá sa ti dať tie kódy bez scrollu? :/ radšej by som to dal bez scrollu do spoileru ako takto. :)
Gelidus
 
Příspěvky: 14
Registrován: 17 listopad 2011 11:56:47

Re: "Commander" v Jave

Příspěvekod Ariczek » 19 srpen 2012 21:42:07

Tebe bych chtěl mít v týmu :D nevím proč, ale tvůj kod se mi hrozně blbě čte :D

přidám pár poznámek:

* pokud seš v metodě objektu, a chceš volat jinou metodu či proměnnou toho sameho objektu - nemusis volat přes this, ale můžeš přímo přímo

Kód: Vybrat vše
this.CommandMap = new HashMap<>();
CommandMap = new HashMap<>();


jediny pripad kdy to neplati - kdyz predavas jako parametr neco co se jmenuje stejne jako vnitrni promenna.
Kód: Vybrat vše
this.map = map;


* z Cele třídy Command bych udělal Interface/Abstract Class.
resis commandy pres dedicnosti, ale nemas ji tam zduraznenou - takhle napsany by ti to nemuselo fungovat - na nejake mene standardni jave. A pak to debugovani proc to nejde bych delat nechtel ;)

* pro kopirovani poli bych zvazil pouziti http://docs.oracle.com/javase/6/docs/ap ... rrays.html a metod na copy - obecne to bude rychlejsi nez na tvrdo napsanej for cyklus :) navic se seknes nekde v indexu a budes to debugovat tyden.
pripadne tady konkretne by slo cele odstraneni prvniho tokenu, a predani zbytku vyresit docela elegantne pres http://docs.oracle.com/javase/6/docs/ap ... nizer.html

* ExampleCommand - ale fuj! vytvaret kvuli jednorazovemu pouziti interni tridu s modifikatorem public ?? Chces poskytovat na venek moznost vytvoreni instance subcommandu pres obskurnost jako:
Kód: Vybrat vše
ExampleSubCommand subCmd = (new ExampleCommand("prvy")).new ExampleSubCommand("treti");

slo by to vyresit mnohem elegantneji pres interface/private modifikator.
Ariczek
 
Příspěvky: 51
Registrován: 21 říjen 2011 10:54:52

Re: "Commander" v Jave

Příspěvekod Gelidus » 23 srpen 2012 14:18:47

Ari díky za odpoveď :) toto bola moja prvá vec čo som v Jave písal vôbec. Snáď to raz prepíšem do riadnej podoby, viac sa zaoberám C#.

K tomu this. , je to zvyk no. vo visualku to dávam všade tiež, aby som vedel že to patrí k tej triede. Okrem toho mi príde lahšie v NetBeans napísať this.(zoznam) + ENTER :D ako písať všetko - niekde sa pomýlim a zas to prepisovať.

Abstraktná trieda - s tým súhlasím, asi ma to v tej chvíli nenapadlo :boxed:

K čitateľnosti, čo presne sa ti na tom zle číta? :) ťažké porozumenie metódam (mal by som ich zjednodušiť) ?

No a nakoniec polia ... :sick: s poliami sa bijem od začiatku, čo som začal s C. Preto radšej používam kontajnery, ale prišlo mi to blbé rvať to do kontajneru.

Každopádne vrelá vďaka za komentovanie celého scriptu :)

Geli
Gelidus
 
Příspěvky: 14
Registrován: 17 listopad 2011 11:56:47


Zpět na Java

Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 1 návštěvník


cron