7 Software Engineering Principles for Developers


In another article called?Architecture Knowledge Reuse Pyramid for Developers, I presented a knowledge pyramid?to show levels of architecture knowledge reuse. One level is Software Engineering Methodology. In this article, I will list 7 software engineering principles to show what the methodology could be.

1. Create solution for problem please

I often see smart developers have the tendency to over-engineer and create a solution that doesn’t have convincing causes. The contributing factors of this over-engineering could be lacking of understanding the tech and the problem domain, over-zeal for anything new, pursuit of perfection ....... A good solution solves real world problems, this should be the first and foremost principle of any software development/engineering practices.

  • Practice Example: Android has Local Broadcast that is within a process and OS Broadcast and is across processes. If an app doesn't need share info with other apps, there is no need to use OS Broadcast that more complicated to implement. If we use a OS Broadcast to resolve in process communication problem, we are creating a solution for a problem that doesn't exist.

2. Keep solution simple please

Not only solution should solve real world problems, but also developers should strive to find the simplest solution to address the problems.

  • Practice Example: if we can name a variable clearly under the context, we should not use one more extra letter.

3. Separate concerns

We humans are not all knowing. To address a problem, we need to divide the problem into components and conquer individual components. Layers, modules, files, classes, functions…. Are the various ways to separate the concerns. Each component should do a single responsibility(high cohesive), the interfaces between components should keep the dependencies between components minimum(loose coupling)

  • Practice Example: Android app architecture usually separates the concerns into layers of ui, domain and data. Inside each layer, it further separates concerns into features.
  • Practice Example: In aspect programming to address the cross-cutting Exception handling concerns, we can centralize the exception handling in a few classes instead of spreading try-catch everywhere,.

4. Fail early, fail often

Interfaces are the contracts between two components when we separate concerns. The components could be software components, people, teams…….Problems arise much more often between components than inside component. When a problem arises, don’t delay to solve it. Create environment to expose these problems often and early so that they can be addressed without causing snowball effects.

  • Practice Example: use Assert to expose errors of function calls during development phase
  • Practice Example: When a team of two developers are working on the same code base using Git, each of them works on his own branch. So instead of letting them work independently for a month and then merge their changes. A fail early and fail often approach would use merging cycles of days. When merging, the problem of discrepancy would be exposed and dealt without leading to much greater damages.
  • Practice Example: When designing/developing a software system, the interfaces design should have a higher priority than the internal design of each component, these interfaces could be UI design, REST API design, communication protocol design…

5. Try , err and improve

In a ever changing and fast moving world today, a grand design and thinking ahead for a long period of time doesn't work well. Rather than spending too much time to find a comprehensive solution, we should spend time to create an adaptable skeleton(lean) solution that the components of the solution can be switched in/out with minimum impacts. Then we try the latest tech to build the components, let error happen because we usually don't have time to gain the full knowledge of the tech and improve the components when opportunity arises.

  • Practice Example: The clean architecture is very good example of the adaptable lean solution for a mobile app. Based on it, we can use the latest mobile tech to try, err and improve the data and presentation layers.

6. Don’t repeat yourself

Machines are good at repeating routines. When we are designing a solution for a problem, we should ask ourselves: "how can we avoid the repetitive steps of the solution and let them be done by machines."

  • Practice Example: The mobile QA/release process should be automated to be done by one button click.
  • Practice Example: The common logic shared by 2+ components should be abstracted out and put in a routine to be called by the components.

7. You are dealing with humans!

As a developer, we tend to think we just need to handle machines and that's an easier job than dealing with humans. But actually, we are dealing with humans directly and indirectly. We are producing a product to serve human needs and wants. Our clients are demanding humans. We need to work in a team composed of humans of diverse spirits. We need to work on other humans' code and our code is worked on by other humans. So we are not just communicating with machines, we are communicating to humans through machines.

  • Practice Example: Make our code easier to read by other humans. Create design doc to explain our thoughts of why and how.
  • Practice Example: When choosing a language, a tool, a framework, a pattern…, consider the context of people and ask the questions of: “will client’s tech team be OK to use it? Will client be persuaded to pay for it? Can the dev team be proficient to use it and deliver?

要查看或添加评论,请登录

Paul Zhou的更多文章

社区洞察

其他会员也浏览了