Generally, I try to design applications in such a way that there is one object/class structure which is specifically concerned with “the web application,” and these objects in turn employ another set of objects/classes which are designed to be agnostic. You wind up looking at the task in front of you from two different levels of concern. The first level is one that does not care how the request is being made; that is strictly concerned with the job and how to do it. “An application,” any application web-or-not, is obliged to use them in some certain, correct, way. The second level is strictly concerned with the flow of “web application” screens and with the steps needed to populate them. It uses the first set of objects to do so. (So the web-app doesn’t look as you might expect ... no database queries in the (web-app) “model” layer, for instance. Likewise, the worker objects don’t reflect MVC.)
The reason why I do it this way is that, no matter how hard a web-application framework strives to be “general,” it is very constrained by the strictures of the HTTP protocol. It has a lot of baggage that has to be there, and the class-structure of any framework is unavoidably designed with the presence of that baggage in mind. I look upon the web-app as simply a user interface.