java - Chain of responsibility pattern - tight coupling with descendants -


i came problem how put actions chain possibility pass additional parameters during processing of action.

let's consider simple chain of processes. input object representing image. first image resized, deployed ftp , saved db. using chain of responsibility pattern, calling this:

imageprocessor p = new imageresizer(desiredsize); p.setnext(new (new imagedeployer(ftpserver, path))); p.setnext(new (new imagedbsaver(dbconnection, table))); p.process(image); p.close(); 

this working 1 image. process images in loop , set desiredsize , path there. cannot create , close connections every time, code has spread:

imageprocessor p = new imageresizer(); p.setnext(new (new imagedeployer(ftpserver))); p.setnext(new (new imagedbsaver(dbconnection, table)));  for(image image : images) {   p.process(image, size, path); } p.close(); 

a problem of solution imageprocessor shouldn't know size , path. in case when used imagedbsaver parameters size , path doesn't make sense.
better way how it?

i guess robust solution in case add kind of processing context.

in simplest case, can (1) use, example map<string, object> this, (2) pack arguments specific various processors, (3) pass p.process(...) , (4) extract, example size in processor resizes image.

this way you'll flexibility add new arguments without need change signature of imageprocessor , keeping implementers decoupled form 1 another.

the real world example of similar request\session\servlet contexts in java ee. can put stuff them on various lifecycle stages (for example security configuration options urls should require auth) , fetch stuff needed (for example in filter block\allow access resource based on auth requirements).

update

updating answer code example demonstrate idea.

so, somewhere in code have place build processor chain:

imageprocessor p = new imageresizer(desiredsize); p.setnext(new (new imagedeployer(ftpserver, path))); p.setnext(new (new imagedbsaver(dbconnection, table))); 

in (possibly) other place create , configure processing context (it not required configure processors in 1 place):

map<string, object> context = new hashmap<string, object>(); context.put("image_width", new integer(640)); 

in place in code processing, passing context (i reuse context processings might use different contexts every image):

for(image image : images) {   p.process(image, context); } p.close(); 

now, somewhere in imageresizer:

@override void process(image image, map<string, object> context) {      // ...      integer imagewidth = (integer) context.get("image_width");      // ...  } 

so, context common place helps deliver data specific processors, abstracting details data , decoupling specific processors 1 another.


Comments

Popular posts from this blog

basic authentication with http post params android -

vb.net - Virtual Keyboard commands -

css - Firefox for ubuntu renders wrong colors -