开发者

How to refactor a Rails model that contains significant amount of back-end code?

I have a Rails 2.X model with 421 lines of code/comments that does a significant amount of work on the backend (opening HTTP Get requests, parsing RSS, parsing HTML, etc.). At the same time, I'm moving to Resque in order to more quickly get through this backend code. I'm wondering what the best way to refactor this would be. Should I move this back-end code to a library that I include in the model? A module? A gem?

Your thoughts would be much appreciated.

I basically have a separate core tasks for each data item i'm processing. i.e. parsing an RSS feed, parsing a HTTP URL, running regex on that html body, as well as a few other tasks and right now i have 500 or lines of code within the model; even though most of the stuff the model does is called through a back-end script run by cron

So to make it more wieldy and to make 开发者_开发百科it easier to move to resque; i was thinking of doing separate classes for each resque queue, and using static methods there

Then I can require those classes by the back-end 'controller' script if you will... Does this approach make sense?


Your best bet from a testability and thought process standpoint is probably to break out those various concerns into their own (non-ARec) models. You might have RssParser, HtmlParser, ServiceRequest, etc., based on your first paragraph.

Depending on where this stuff is used (multiple projects?), it might make sense to make your own gem and version it.

I have written big and small resque classes before, and you'll save yourself a lot of pain if you make the resque classes as thin as possible.


The model in question is doing many things.

In a well-structured application, every class does one thing and does it well. This feature of a well-structured application is part of what makes it highly testable.

You should break apart the many things that the one model does into multiple self-contained classes, keeping the dependencies between them minimal. Then you will be able to test each of those new classes easily, and you will have a number of new stub points to test the overall model.


In my experience, if this code is going to be used in more than one application, maybe a gem is worth considering. Otherwise, adding the layer of indirection by moving the code to a gem doesn't seem to yield much benefit. In fact it can potentially slow down development depending on your deploy situation.

As for how to re-factor the model, look through all the model's code and as yourself the question "What is this model doing?". If you end up with lots of 'and's or 'or's, then you should probably strive to make each item delimited by 'and' or 'or' its own class (see http://en.wikipedia.org/wiki/Single_responsibility_principle). Breaking out the responsibilities in this manner makes the individual concerns much easier to write tests against. Especially when making external HTTP api calls, etc.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜