Follow Up to the comment:
My original intent was just to suggest a problem domain whereby you could break each part of the entire system into more meaningful portions whereby the students could clearly see a need for each pattern. I figured instead of several unrelated tasks you could follow this idea for several larger tasks and let them see how it would all work together. That might be too much for a student now that I think about it and it didn't really address your issue.
Here's a real life example
Sale(Integer_quantity, ICatalogItem _item, IDiscount _discount) implements ITransaction
Refund(Double _amount, IOrderNumber _orderNumer) implements ITransaction
These came about because someone decided to use a magical number "-1" to indicate no sale. You can imagine what happened when people put in a refund for 1 dollar. The IDiscount
was, of course, a Strategy pattern to calculate the price of the sale. We had an abstract factory object to create all the sales.