View previous topic :: View next topic |
Author |
Message |
assente Guru
Joined: 12 Apr 2004 Posts: 570 Location: Torino, italia, New Europe
|
Posted: Mon Oct 10, 2005 1:25 pm Post subject: [OT DEV] Sviluppare applicazioni GUI-independent |
|
|
Ho fatto questo script in ruby di prova che a seconda dell'argomento si avvia con la GUI o con la console.
La struttura è banale classe principale List e poi le interfacceGtkList e ConsoleList che lo estendono e si occupano dell'interfaccia I/O, adesso mi viene ho 2 dubbi,
1. secondo voi il controllo della validità dei dati deve essere fatta anche a livello interfaccia?
(Per esempio chi deve segnalare se un'entry è null? l'interfaccia o l'oggetto centrale? Se si fa a livello GUI non si rischia di inconsistenza rispetto le altre GUI che ci possono essere?)
2. nel caso il dato non sia valido è meglio che l'oggetto principale lanci un'eccezione o che implementi un metodo d'errore a livello superiore?
(Se si usano le eccezioni non si rischia di implementare i messaggi di errore nelle interfacce - e quindi duplicali? - )
Chiedete pure se non mi sono spiegato bene o se avete implementazioni più efficaci da proporre.
Code: |
#!/usr/bin/ruby
=begin
== esempio.rb ==
Una semplice implementazione di oggetti indipendenti dall'interfaccia grafica/console
oOo. http://assente.altervista.org .oOo
=end
# Oggetto principale GUI-indipendent
class List
def initialize()
@a=[]
end
def add(value)
# vari controlli sull'input
if value==""
error("Valore nullo")
elsif value=~/[a-zA-Z]/
error("Le lettere non sono ammesse")
elsif value=~/[0-9]/
@a << value
notify("'#{value}' inserito")
end
end
# yield viene sostituito con quello che passiamo a livello superiore,
# puts oppure @display.text+=, fantastico, no?
def show_all
@a.each { |value| yield value}
end
end
class ConsoleList < List
def initialize
super
puts "Console mode"
while true
puts "1: Aggiungi 2: Visualizza 3: Esci"
# toglie \n dall'input da terminale
choice=gets.strip
case (choice)
when "1" then add
when "2" then show_all
when "3" then exit
else
error("Scelta non valida")
end
end
end
def add
puts "Inserisci: "
# manda al metodo List#add vedi su
super(gets.strip)
end
# Richiamato da List
def error(text)
puts "!! #{text} !!"
end
def notify(text)
puts ">> #{text}"
end
def show_all
super{|v| puts "|#{v}|"}
end
end
class GtkList < List
require 'gtk2'
def initialize
super
puts "GUI mode"
Gtk.init
#Inizializzo i widget
@window=Gtk::Window.new
@container=Gtk::VBox.new
@entry=Gtk::Entry.new
@display=Gtk::Label.new
@button=Gtk::Button.new("Inserisci")
#Assegno gli eventi
@button.signal_connect("clicked"){add}
@entry.signal_connect("activate"){add}
@window.signal_connect("destroy"){exit}
#impacchetto
@container.add(@display).add(@entry).add(@display).add(@display).add(@button)
@window.add(@container)
@window.show_all
Gtk.main
end
def add
puts "Inserisci: "
super(@entry.text)
@entry.text=""
end
def error(text)
# Con più spazio estendetevi Gtk::Alert :-)
Gtk::Window.new.add(Gtk::Label.new("#{text}")).show_all
end
def notify(text)
# Non necessario
#Gtk::Window.new.add(Gtk::Label.new("#{text}")).show_all
show_all
end
def show_all
@display.text=""
super{|v| @display.text+=v+" "}
end
end
# Inizia qui
case(ARGV[0])
when nil: ConsoleList.new
when "--gtk": GtkList.new
end
|
_________________ Blog
E8400, 4850, P5q |
|
Back to top |
|
|
federico Advocate
Joined: 18 Feb 2003 Posts: 3272 Location: Italy, Milano
|
Posted: Mon Oct 10, 2005 3:37 pm Post subject: |
|
|
Il controllo della consistenza dei dati la farei a livello di programma e non di interfaccia, esattamente per il motivo che hai citato tu.
Per gli errori, farei sollevare un eccezione, che l'interfaccia grafica puo' poi gestire nel modo che piu' le aggrada _________________ Sideralis www.sideralis.org
Pic http://blackman.amicofigo.com/gallery
Arduino http://www.arduino.cc
Chi aveva potuto aveva spaccato
2000 pezzi buttati là
Molti saluti,qualche domanda
Semplice come musica punk |
|
Back to top |
|
|
assente Guru
Joined: 12 Apr 2004 Posts: 570 Location: Torino, italia, New Europe
|
Posted: Mon Oct 10, 2005 8:03 pm Post subject: |
|
|
ok grazie per la delucidazione, anche se mi piaceva l'idea di implementare error("x non valido") a livello di programma, pensandoci bene c'è anche un'altro contro: con l'eccezione non viene eseguito il codice sottostante ed è giusto che sia così _________________ Blog
E8400, 4850, P5q |
|
Back to top |
|
|
federico Advocate
Joined: 18 Feb 2003 Posts: 3272 Location: Italy, Milano
|
Posted: Mon Oct 10, 2005 9:44 pm Post subject: |
|
|
Potresti fornire anche qualche specifica per la gestione delle eccezioni, per esempio se tu facessi un substrato software per la gestione di mp3 e due persone decidessero di fare un'interfaccia, magari all'evento mp3 non trovato tu sollevi un eccezione, e la prima gui che ne so, decide di scaricare l'mp3 non trovato, e la seconda decide di proporti canzoni dello stesso autore, bhop... ahhah che esempio pessimo _________________ Sideralis www.sideralis.org
Pic http://blackman.amicofigo.com/gallery
Arduino http://www.arduino.cc
Chi aveva potuto aveva spaccato
2000 pezzi buttati là
Molti saluti,qualche domanda
Semplice come musica punk |
|
Back to top |
|
|
assente Guru
Joined: 12 Apr 2004 Posts: 570 Location: Torino, italia, New Europe
|
Posted: Mon Oct 10, 2005 10:37 pm Post subject: |
|
|
sì.. però mi piaceva anche l'idea di avere tutte le stringhe da tradurre in un solo posto.. e quindi lanciare l'eccezione con la stringa d'errore insieme.
lancia EccezioneStandard.new("Mp3 non trovato")
lancia Mp3NotFound.new
Nel primo caso ho la comodità di stabilire la stringa d'errore dal programma, nel secondo la devo poi definire nella GUI; il primo mi sembra meno ridondante, ma il secondo è più flessibile, metti che una gui voglia fare citare widget specifici.
Comunque sia, se l'errore comporta anche delle modifiche nella GUI bisognerebbe comunque specificare eccezione->azione e distinguerle dall'errore delle stringhe sarebbe troppo grezzo, no?
Quindi i livelli sono: Interfaccia con stringhe d'errore che intercetta le eccezioni e programma che lancia eccezioni _________________ Blog
E8400, 4850, P5q |
|
Back to top |
|
|
riquito Tux's lil' helper
Joined: 17 Jul 2002 Posts: 93
|
Posted: Tue Oct 11, 2005 9:27 am Post subject: |
|
|
assente wrote: |
Quindi i livelli sono: Interfaccia con stringhe d'errore che intercetta le eccezioni e programma che lancia eccezioni |
Non esattamente. Direi piuttosto
"programma che lancia eccezioni" e "interfaccia che intercetta le eccezioni e mostra le relative stringhe di errore"
la parte di computazione indipendente dalla gui deve generare eccezioni in caso di errore, contenenti informazioni utili.
La gui deve leggere dall'eccezione la stringa che indica il problema riscontrato, ed eventualmente mostrare all'utente la stringa incapsulata nell'eccezione (via shell o via libreria grafica a seconda del tipo di GUI).
Ciao,
Riccardo _________________ Sideralis Programs
http://www.sideralis.org |
|
Back to top |
|
|
assente Guru
Joined: 12 Apr 2004 Posts: 570 Location: Torino, italia, New Europe
|
Posted: Tue Oct 11, 2005 3:11 pm Post subject: |
|
|
quindi con la stringa d'errore impacchettata nell'eccezione tipo:
Code: |
class Controller
def initialize(word)
if ["ciao", "tizio", "caio"].include?(word)
raise ArgumentError, "'#{word}' non ammesso"
else
raise "'#{word}' valido"
end
end
end
class GuiController < Controller
def initialize(value)
begin
super(value)
rescue ArgumentError => e
puts "!!! "+e
rescue => e
puts ">>> "+e
end
end
end
GuiController.new("pinco")
GuiController.new("ciao")
GuiController.new("pallino")
|
Ma a sto punto sarebbe anche il caso di lanciare un'eccezione se tutto èandato a buon fine? ..e poi decidere a livello gui se è il caso di mostralo? _________________ Blog
E8400, 4850, P5q |
|
Back to top |
|
|
riquito Tux's lil' helper
Joined: 17 Jul 2002 Posts: 93
|
Posted: Tue Oct 11, 2005 5:56 pm Post subject: |
|
|
assente wrote: | quindi con la stringa d'errore impacchettata nell'eccezione tipo:
Code: |
class Controller
def initialize(word)
if ["ciao", "tizio", "caio"].include?(word)
raise ArgumentError, "'#{word}' non ammesso"
else
raise "'#{word}' valido"
end
end
end
class GuiController < Controller
def initialize(value)
begin
super(value)
rescue ArgumentError => e
puts "!!! "+e
rescue => e
puts ">>> "+e
end
end
end
GuiController.new("pinco")
GuiController.new("ciao")
GuiController.new("pallino")
|
Ma a sto punto sarebbe anche il caso di lanciare un'eccezione se tutto èandato a buon fine? ..e poi decidere a livello gui se è il caso di mostralo? |
Non conosco ruby, ma python, e mi sembra di capire che in Controllore tu generi una eccezione con raise anche se il dato e' corretto, giusto? questo e' un uso improprio delle eccezioni: come dice il nome, devono indicare qualcosa di anomalo, e solo quello.
in python farei una cosa del genere, seguendo il tuo codice
Code: |
class Controller(object):
def __init__(self,word):
if word in ["ciao", "tizio", "caio"]:
raise ArgumentError, word+" non ammesso"
class GuiController(Controller):
def __init__(self,value):
try:
super(GuiController,self).__init__(value)
print ">>>",e
except ArgumentError,e:
print e
|
forse l'esempio snatura le tue intenzioni, ma il controllo della validità di un argomento e' piu' lavoro di una funzione che di una classe, e soprattutto tu, in qualunque caso, "fai creshare" l'inizializzazione della classe Controller: non dovrebbe mai accadere.
Spero di esserti stato utile.
Ciao,
Riccardo _________________ Sideralis Programs
http://www.sideralis.org |
|
Back to top |
|
|
assente Guru
Joined: 12 Apr 2004 Posts: 570 Location: Torino, italia, New Europe
|
Posted: Tue Oct 11, 2005 7:25 pm Post subject: |
|
|
Python e Ruby non sono molto diversi, sì genero un'eccezione anche se il valore è valido, sono quasi sicuro che non si fa così, però in alcuni casi potrebbe essere utile segnalare/notificare che: "il valore x è stato aggiunto correttamente", come lo faresti senza eccezione? Lo supporresti dalla GUI? visto che non si è fermato prima allora tutto è andato bene?!
Certo lanciare eccezioni da init non va bene, ma era solo per far vedere che partivano dall'oggetto interno.
Per il resto mi sembra tutto molto simile, tranne per il fatto che io ho esteso Controller con GuiController e tu invece lo passi come argomento. _________________ Blog
E8400, 4850, P5q |
|
Back to top |
|
|
riquito Tux's lil' helper
Joined: 17 Jul 2002 Posts: 93
|
Posted: Wed Oct 12, 2005 9:36 am Post subject: |
|
|
assente wrote: |
- in alcuni casi potrebbe essere utile segnalare/notificare che: "il valore x è stato aggiunto correttamente"
|
non mi vengono in mente casi utili, tranne quando devi _attendere_ che il dato sia stato processato e inserito e ti aspetti un segnale che ti informi (caso di thread o programmazione concorrente)
assente wrote: |
- come lo faresti senza eccezione? Lo supporresti dalla GUI? visto che non si è fermato prima allora tutto è andato bene?!
|
Non lo suppongo dalla GUI perche' e' la chiamata tramite super che va a buon fine, e si, visto che non si e' fermato andra' tutto bene. Questo e' l'approccio con le eccezioni. Se non ti piace, puoi usare uno stile procedurale, e farti ritonare valori utili da una funzione (0,1 - vero,falso o altro), che ti indica esplicitamente se la chiamata e' andata a buon fine oppure no.
assente wrote: |
Certo lanciare eccezioni da init non va bene, ma era solo per far vedere che partivano dall'oggetto interno.
|
ok
assente wrote: |
Per il resto mi sembra tutto molto simile, tranne per il fatto che io ho esteso Controller con GuiController e tu invece lo passi come argomento. |
Erano poche righe di codice, che ti aspettavi?
Ciao,
Riccardo _________________ Sideralis Programs
http://www.sideralis.org |
|
Back to top |
|
|
gutter Bodhisattva
Joined: 13 Mar 2004 Posts: 7162 Location: Aarau, Aargau, Switzerland
|
Posted: Sat Oct 29, 2005 10:17 pm Post subject: |
|
|
Moved from Italian to Off Topic. _________________ Registered as User #281564 and Machines #163761 |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|