Your problem fits squarely into the single responsibility principle (SRP), one of the SOLID principles.
The principle essentially states that a well designed component should only ever be responsible for a single task. Another way of looking at it is that the component should only ever have one reason to change. This makes sure that when you need to change something, you know all the functionality will be in a single place and wont be mixed with other functionality.
In your case, a Job
presumably has some kind of functionality other than printing, perhaps some responsibilities to represent a "job" in your domain model. If it does, then you don't want to add printing functionality here. Instead create your print widget and put all the logic for printing there.
If your printing has to change, you wont have to touch your Job
object, because its responsibilities haven't changed. Likewise if the concept of a "job" changes, only the Job
class is modified and the printing remains unaffected (unless you now have something extra to print).
However...
If the only purpose of the Job
class is to represent some information for printing, then it most definitely should contain a PrintTo(Printer)
method, where Printer
would be responsible for talking to a physical printer. In this case the responsibility has shifted to Job
being only involved in printing and it's appropriate it should control how it is printed.
SRP can be a difficult pattern to see in your designs, but there is a simple way to be sure:
If you can sum up the functionality of
your class without using the word
"and", the class has a single
responsiblity.
So, Job
is either responsible for "representing a job" or "printing job information", but not both.