EDIT: I added a bit here on how I would do it better without needless refactoring: http://localhost:3000/2013/02/08/copypasta/#a-better-solutio...
def global_feed(request):
tweets = Tweet.objects.all()
tweets = itertools.ifilter(lambda t: not t.is_profane(), tweets)
return render(request, 'global_feed.html', {'tweets': tweets})
tweets_per_page = 20
def user_timeline(request, username):
tweets = Tweet.objects.filter(user__username=username)
page = request.GET.get('page', 1)
offset = (page - 1) * tweets_per_page
tweets = tweets[offset:offset + tweets_per_page]
return render(request, 'user_timeline.html', {'tweets': tweets})So the two unpleasant scenarios seem to be this:
1) The OP's assertion that DRYing the code may unintentionally break functionality in all the places that use it.
2) The DRY assertion: copy-pasting functionality, such as pagination, makes it more likely that the pagination functionality won't be properly updated across all the modules that use it.
I guess it's a case of YMMV...because in this hypothetical app, it doesn't seem likely that the number of views will multiply, thus making it easier to update the copy-pasted code. But that seems like a mindset as prone to future problems than one that is more DRY-minded.
Couldn't the problematic DRY pattern be alleviated by refactoring the following call:
Into something like: Why does the logic for the Tweet filtering have to be encapsulated in the rendering function?// edit:
What might help is if the OP showed how the non-refactored code would look with the profanity_filter and pagination features. I agree that his refactored proposal is confusing...I'm just having a hard time imagining how the non-refactored version would be less so.