EventSourcing sounds like the pattern that you may be looking for.
Let's take an example using a simple "car" object that we would want to keep track of the color of (pseudo C# code follows).
public class Car {
public string Color { get; set; }
public Car() { this.Color = "Blue"; }
}
With a CRUD implementation when we update the color of the car the previous color would be lost.
MyCar.Color = "Red";
MyCar.Save(); // Persist the update to the database and lose the previous data
This loss of information sounds to me like what you would like to avoid the most (hence the dislike for the update and delete part of the CRUD pattern).
If we were to rewrite the car class to instead respond to events when updating its change it may look like this:
public class Car {
public string Color { get; private set; } // Cannot be set from outside the class
public void ApplyEvent(CarColorChangedEvent e) {
this.Color = e.Color;
}
}
Now how would we update the color of this object? We could create a CarColorChanged event!
var evnt = new CarColorChangedEvent("Red");
MyEventStore.save(evnt);
MyCar.ApplyEvent(evnt);
Notice the lack of a save on the actual model object? That's because instead of persisting the model directly we persist the events that put the model to the current state. These events should be immutable.
Now's let's fast forward and change the color a few more times:
var evnt = new CarColorChangedEvent("Green");
MyEventStore.save(evnt);
MyCar.ApplyEvent(evnt);
var evnt = new CarColorChangedEvent("Purple");
MyEventStore.save(evnt);
MyCar.ApplyEvent(evnt);
If we were to look at our event storage (could be a relation database, file based, etc..) we would see a series of events relating to our car object:
CarColorChangedEvent => Red
CarColorChangedEvent => Green
CarColorChangedEvent => Purple
If we wanted to rebuild that car object we could do so simply by creating a new car object and applying the events from our eventstore to said object.
var MyCar = new Car();
var events = MyDatabase.SelectEventsForCar("CarIdentifierHere");
foreach(var e in events) {
MyCar.ApplyEvent(e);
}
Console.WriteLine(MyCar.Color); // Purple
With the stream of events we can roll back the state of the car to a previous time period simply by creating a new car object and only apply the events that we want:
var MyCar = new Car();
var event = MyDatabase.GetFirstEventForCar("CarIdentifierHere");
MyCar.ApplyEvent(e);
Console.WriteLine(MyCar.Color); // Red
Is there a term for this? Basically only creating and reading data?
Sure there is: CR ;P