abstraction layer software development