I advise you not to have the object-oriented programming hammer as
your only tool, because it's easy to then treat every problem as
though it were a nail.
Naturally! But then.. knowing when to use a given programming technique
is part of the problem. I have a spouse who just ruined a perfectly good
chef's knife that cost me about $80.00 because she didn't bother looking
for a screwdriver .. and thank goodness I didn't have to take her the ER
to boot.
What you describe seems trivially a procedural sequence of branching
steps using simple types from the standard library.
This is for a standalone laptop.
I went to the trouble of designing, coding, and cron'ing my B/U script
for two reasons:
1. I wanted the laptop backed up regularly and -- see other posts in
this thread.. "restorable".
2. The more I worked on this project, the more interesting it became ..
along "what happens if" lines .. and less trivial.
Now that's over and done with.
But then I started thinking .. what if for instance I had to scale my
effort from my single system to a large "data center" with hundred of
hosts .. with different backup policies .. what if I had to take into
account time slots where the backups ran .. had to consider bandwidth &
performance issues .. media costs & their rotation and such like.
In a vague way I had this feeling that if added machines one at a time,
my current script would not scale all that well.
I hope I'm making some sense but this is why, rather than take your word
for it, which I tend to intuitively agree with anyway .. I would much
prefer trying to oop this myself and try to figure why in this instance
using object-orientation would probably only add much overhead and
complexity without any real benefits.
IOW--we only learn by our own mistakes.
Use functions to encapsulate the conceptually-related steps, and call
those functions in a simple branch as you demonstrated. I see no need
to apply object-oriented techniques for this problem.
import datetime
def is_full_backup_required(when):
""" Determine whether a full backup is required for datetime 'when' """
result = False
if determine_whether_full_backup_required_for_datetime(when):
result = True
return result
def most_recent_incremental_backup(when):
""" Return the most recent incremental backup before datetime 'when' """
backup = most_recent_backup(when)
return backup
def save_previous_full_archive(when):
""" Save the full archive previous to datetime 'when' """
def save_previous_incremental_archive(when):
""" Save the incremental archive previous to datetime 'when' """
def perform_full_backup(system):
""" Do a full backup of the system """
def perform_incremental_backup(system):
""" Do an incremental backup of the system """
def get_this_system():
""" Return the current system for backups """
system = determine_what_this_system_is()
return system
system = get_this_system()
when = datetime.datetime.now()
if is_full_backup_required(when):
save_previous_month_archive(when)
perform_full_backup(system)
else:
save_previous_incremental_archive(when)
perform_incremental_backup(system)
Thank you very much for providing this example skeleton.
I don't see any need for creating new classes for any of this, unless
a "system" is more complicated than just a string for the system
name, or a "backup" is more complicated than a tarball file.
Well .. relative to my far-fetched example of scaling above .. I thought
that maybe a "target system" -- one to backup, that is .. would be an
obvious class .. that one could find some criteria or other that would
categorize systems into subgroups .. with related backup policies, for
instance .. and each actual system would end up being an instance of
these latter "sub-classes".
Likewise a "backup" .. full or incremental .. with a system name and a
calendar date as natural attributes ..?
No harm in trying?
Instead, the problem seems one best solved simply by abstracting the
steps involved at each point of the *procedure*, as I've done in my
example.
To loosely quote someone's post on this thread .. I have AFAIK already
"solved" my problem .. So why bother? .. As indicated above this is a
case of looking at the problem from a different angle and hopefully
learn something.
Each one of those functions could be very simple or could be
complex enough to spawn a whole host of helper functions, possibly
even separate modules. That seems a more useful approach than trying
to force-fit object-orientation to this procedural problem.
Begs the question .. how do I tell what is an object-oriented vs. a
procedural problem?
Also, what classes of problems would be naturals for OOP?
Thanks!
CJ