печально быть антисоциальным - Komandu patterns

Dec. 22nd, 2003

07:13 pm - Komandu patterns

Previous Entry Add to Memories Tell A Friend Next Entry

Datu atjaunošana, satura ģenerēšana aizņem laiku. Dažreiz nevajag, tūlītējus rezultātusvai aizkavēšanās nav būtiska. Sistēmās, kas atbalsta vairākus pavedienus [multithreading], var to darīt paralēli.

Man ir web aplikācija, kas griežās uz 1.x Apačiem un tas nav iespējams. Risinājums vienkāršs: atliku lēnos darbus uz programmas beigām un pa priekšu atgriezu HTML. Kā tas tiek darīts, tiks ilustrēts piemērā:




class Task(object):

def do(self):
"Must be implemented in subclass!"
pass

class Tasks(list):

def add(self, task):
print "task " + task.__class__.__name__ + " added!"
self.append(task)

def do(self):
if tasks:
print('starting tasks >>')
for index, task in enumerate(self):
print index, " ", task.__class__.__name__ + " >>"
task.do()
print '<< done.'
print '<< all tasks done!'


class InsertInDB(Task):

def __init__(self, data):
self.data = data

def do(self):
print "inserting " + str(self.data) + " in DB"

class Reindex(Task):

def do(self):
print "Reindexing indexes"


class Sleep(Task):

def __init__(self, howLong):
self.howLong = howLong

def do(self):
import time
print "Sleeping " + str(self.howLong) + " seconds"
time.sleep(self.howLong)
print "hmmm..."


tasks = Tasks()


tasks.add(InsertInDB(1))
tasks.add(InsertInDB("Tramvajs"))
tasks.add(Reindex())
tasks.add(InsertInDB(4))
tasks.add(Reindex())
tasks.add(Sleep(2))


tasks.do()


Klases Task apakšklases InsertInDB, Reindex, Sleep, katra izpilda savu uzdevumu, kad to instancēm tiek pasaukta metode do. To savukārt dara Tasks instance tasks.

Šajā realizācijā uzdevumi tiks pildīti tādā secībā, kādā tie ievietoti, bet citos gadījumos varbūt ir labāks risinājums. Iespējams, kāds uzdevums vairs nav aktuāls.

Piemēram, indeksāciju jāveic tikai vienreiz. Papildinām kodu ar dažām rindiņām:


class ReindexOnce(Tasks):

def mustReindex(self):
for task in self:
if isinstance(task, Reindex):
return True
return False

def fakeReindex(self):
pass

def do(self):
print "ReindexOnce started >>"
if self.mustReindex():
doReindex = Reindex.do #savaacam Reindex.do metodi
Reindex.do = self.fakeReindex #aizvietojam to ar metodi, kas neko nedara
Tasks.do(self) #izpildam paareejos uzdevumus
doReindex(Reindex()) #saucam Reindex.do
else:
Tasks.do()
print "<< ReindexOnce finished"


print "Tagad tie pashi veezhi citaa kuliitee"
tasks.__class__ = ReindexOnce
tasks.do()


Šeit bija daži pitoniski triki, kā objekta metodes un klases aizvietošana. Nedaudz garākā piemērā to pašu varētu realizēt arī citās valodās.

Rezultātā, pievienojot nelielu kompleksitāti komandas ('Task') radīšanā, iegūstam iespēju kontrolēt komandu izpildīšanos.

Mājas lasīšanai:
Command Pattern
Command Oriented Interface

(Leave a comment)