Making Embedded Systems: Design Patterns for Great Software