I'm writing a small and lightweight Django-like back-end framework for myself just for experiment.
If we look at ProcessFormView
view(and some other views):
class ProcessFormView(View):
def get(self, request, *args, **kwargs):
return self.render_to_response(self.get_context_data())
def post(self, request, *args, **kwargs):
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
...
To me it sounds like a valid case to define this class as an "abstract base class".
After all, It needs that sub-classes provide render_to_response()
, get_context_data()
, get_form()
, form_valid()
, form_invalid()
. (They will be provided by TemplateResponseMixin
and FormMixin
.)
I can do something like this:
class ProcessFormView(View, metaclass=ABCMeta):
@abstractmethod
def render_to_response(self, context):
pass
@abstractmethod
def get_context_data(self):
pass
@abstractmethod
def get_form(self):
pass
@abstractmethod
def form_valid(self, form):
pass
@abstractmethod
def form_invalid(self, form):
pass
def get(self, request, *args, **kwargs):
return self.render_to_response(self.get_context_data())
def post(self, request, *args, **kwargs):
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
...
Or even better we can factor these abstract methods out to another ABC class and inherit from it to clear things up.
I know that of course it's a made decision and nothing is wrong with it. I mostly interested to know if do what I just showed, how can it cause problem in future? what would be the cons that I'm not aware of?
The only disadvantage that I can think about is I should then write many abstract classes! This make the code base much bigger.
Aside from the mentioned fact that the code base would become much bigger, I think I found the main reason.
It's true that if we subclass ProcessFormView
and "intend to use its get
and post
method", we have to eventually somehow provide those mentioned methods. But what if for some reason we only want to use its post
method and provide our own custom method for get
? (They are only get called inside post
and get
).
This way we no longer have to implement the render_to_response
and get_context_data()
abstract method. Defining them as abstractmethod
s would unnecessarily force sub-classes to implement them.