The hardest Magic cards are the ones they say, “Do X when Z happens.” I was thinking that each card could register an event with the rules engine. Gruul War Plow says, “Creatures you control have trample.” The event code could look something like this.
Add trample to that creature
Events could also implement replacement effects. Leyline of the Void says “If a card would be put into an opponent's graveyard, remove it from the game instead.”
Remove card from the game
Events are limited type of observers. The event code only wants to know if a specific action took place. While this idea is primitive, it seems like a good way to split up the division between the card code and the rules engine.
The event code would be part of the overall code for that card. It is a good idea to keep the code for each card as separate and self-contained as possible in order to avoid hard-to-find errors and long “if” statements. Many details still have to be hammered out like what arguments does each event need?