I have been engaged in small and micro enterprise information work for more than 10 years, and my own small studio has developed one project after another with members like running water. In more than ten years of experience, I have developed a set of ASP.NET The framework of the project. This set of frameworks from V1 to V8 reflects my deeper understanding of software engineering. Looking back, I can see the trend of my technology learning, the size of design space of each set of frameworks, and the simplicity of developing applications based on frameworks. That’s just right. In the framework of developing V8 recently, I have a deeper thinking and summary on these contents. Write it and share it with you.
Section 1: background
The concept described in this paper has its background and application scope. It’s for small studios to develop projects, not to make products. As my team belongs to the nature of the studio, the mobility of the team members is very high. At the same time, most of the projects I involved are short, flat and fast. After counting the development time of all my projects, I found that the most time I spent was upgrading the framework, followed by small projects. Well, under this premise, it’s not convenient for me to use the automated build tool. As we all know, the most troublesome part of automatic construction is the configuration work at the beginning of the project, and the learning cost of this kind of thing is very high. If it’s a product, learn / configure once and you can use it permanently. My project has a weakness with automated build (in fact, I only use automated build for the front end).
Under this premise, most of my projects share one solution, and I have no staff to maintain the framework project alone. It can only update the project framework (release the design space) in the process of continuous development and use. Until one day, the design space of this framework is used up, and the refactoring is done directly, and then the next one continues.
In fact, this kind of framework is not healthy. I have a look, it seems that no one is specialized in this kind of team. Most people think that this kind of team is actually a failure, a short-lived team, and a small team. However, many small teams I met are in this state. After all, not everyone can come up with a very good product. Even if there are very good products, not everyone can get the investment.
Therefore, the team background corresponding to this paper must meet the following conditions:
1. Your team develops a series of common projects (such as CMS or MIS);
2. Your team must be a small micro team (5-10 people), and there are not enough people to maintain the framework;
3. Your team is very mobile, the level of team members is uneven, and the cost of learning is high;
4. Your funds are very valuable. Maybe the main expenditure of your team is salary;
5. You have a voice in the team.
Section 2: what is design space
This is my own definition of software architecture stability. Design space refers to the space of how much business code is inserted into the framework code without affecting the stability and reusability of the framework. It has two sub concepts, where does the plug-in code not affect the stability and reusability of the framework? What kind of code will not affect stability and reusability? In general, the number of plug-in code locations and code forms are the criteria for judging the size of the design space.
I will give a detailed explanation of the definition of “design space”:
1. The added code must be business oriented
Software code can be roughly divided into two categories: business code and framework code. The so-called framework code refers to reusable code, which is basically available in all your business areas. For example, I focus on the production of school enterprise information system. In this system, there will be users, roles, permissions and organizations. No matter which system user must have ID, name, student / job number, user name and password. Then these classes and fields belong to the framework code. They can be reused, and the framework code will not occupy the design space.
Business code refers to those who focus on a specific business. For example, in the V3 framework era, I am still a Mengxin who works as a school website. At that time, I developed the “online exhibition hall v1.0” system. The system belongs to the CMS system. At that time, the three-tier architecture was used. In this system, there is a class “display board”. So for this class and my business field, I can’t find any place to use this class except this project. Then this class uses the design space of my V3 framework.
2. The added code must affect the stability or reusability of the architecture
Due to the miniaturization of the team, you don’t have the manpower available to maintain the framework project. So, in this case, use the self-developed framework (don’t ask me why I didn’t use the finished framework, when I started working in 2010, ASP.NET In order to ensure the reuse and update of code, the only way you can do is to refer all projects to the same framework. For example, in my V3 framework, all six projects use the same model. Now I don’t have the design tools of that time. I’ll just cut a picture to show you.
Figure 1 context shared by all projects
In this case, you use design space for every class (table) you add. Because you can’t reuse any class except the one you need in the framework. The small team has a very troublesome problem – high mobility of personnel, high cost of learning. It means that it will probably take two or even three weeks for a new person to come to your team. This kind of learning time and process, they will come across a bunch of classes that they can’t use at all. So, in this case, I think these classes encroach on the design space of the framework.
For another example, the workflow module of V3 framework still uses WWF. Here, I wrote a lot of custom activities:
Figure 2 an activity in V3 workflow module
Note that the reusability of these activities is absolutely zero. Because they are for business development, only in “a school laboratory management system” project, these activities can be used. Latecomers do not need to read this module, but need to learn some writing methods in the module. So their existence is very embarrassing, delete is not, do not delete is not. They also encroach on the design space.
In addition to this situation, there are some code that can affect the stability of the architecture. Here we need to introduce that the stability of architecture is different from the reliability of software. Architecture stability refers to the impact of requirements change and code change on software system, which is an empirical quantity. Software reliability refers to the number of errors (or robustness) of a software system in a specific environment, which can be quantified. This paper discusses stability.
This time I came to V4 framework. The background of architecture was in 2015. At that time, I had a very shallow understanding of RBAC system, and I didn’t understand claim based architecture at all. In this case, let’s look at the implementation of getting the user function
Figure 3 code affecting stability
Looking at the code above, you can see that user.IsInRole Directly write the specific roles in the class of SecurityService. This is totally unacceptable because, according to statistics, what my framework calls to get the user’s component is this function to get data, and this component needs to be called tens of thousands of times every day. Even if the system is changed, the user is still the function or the code. So, after changing a system, will there be an “administrator of the Academic Affairs Office”? Obviously, this is impossible. For another example, one day the dean’s office will add a new role, such as “innovation credit administrator”. Yes, that’s what follows or in the above code. Then I need to modify all the affected code, and the architecture is unstable. And to write this kind of code is to release the design space.
Section three: the meaning and measurement of design space
Design space is an important index for me to judge the quality of a framework. The significance of design space lies in how much damage I can do to the system and how much modification I can make to the system. The system with large design space can release part of the design space in exchange for the most efficient modification speed in the face of demand changes.
How to measure design space? I usually use the number of insertion points to size. When I look through the framework code, I will understand which code can be inserted into the business code to achieve the purpose of modifying the requirements most quickly. Adding up these numbers is my way of measuring design space. According to my own practice, the size of design space should not be less than 1.5 times of the total number of required functions. For example, the user module design space of V4 framework is only about 20 after being measured. To develop a user module, I will simply say that there are 16 cruds for users, roles, permissions and organizations. In this case, although the new requirements can also be realized through this framework, they will feel constrained and inconvenient when they are modified.
For example, the above example. In fact, the earliest function (design space is 2) looks like this:
The design space of this function is very large (the size is 2, which is basically where I annotate). Because it’s not business based at all. It can also be seen that when the actual demand comes (that is, only the “administrator of the Academic Affairs Office” and other roles can find users according to part of the student number, while other roles can only find users by entering the complete student / job number), I can quickly copy the above code in the form of freeing up the design space and turn it into the style of Figure 3. This modification can be completed within 5 minutes and deployed within 10 minutes. Then customers will think that you have strong business ability and can quickly modify the system according to their requirements.
Therefore, the ultimate goal of maintaining design space is to quickly modify the system according to the changed requirements. The size of the design space is inversely proportional to the time to change the modification requirements.
Section four: the release and occupation of design space
Since design space is defined, it must be for occupation. Therefore, when to use design space is a very important thing. In my opinion, the use of design space is a very bad thing in the development and design phase of a project. Because at this time, Mingming can keep the design space by modifying the system design, and even leave enough space for future modification. Therefore, in this case, the use of design space, I call it: encroachment. That is, you could not have used it, but you used the space of the future.
After the actual operation of the project, due to the changes in requirements, you may need to respond to these changes as quickly as possible. At this time, you need to release the design space according to the actual needs. For example, today came an important demand, the leader asked you to solve it half a day. This is the design space left before observing the requirements. Then you can use these spaces in the form of direct release to quickly complete the project.
Well, it’s very easy to understand and think of. When the design space of a system is almost released, that is when the system should be reconstructed. When refactoring, it is not only necessary to return the previous design space. It is also necessary to re reserve design space according to the possibility and direction of future demand changes.
Section five: summary
The essence of design space is to embrace change, and the ultimate goal is to quickly modify the changing needs. It reflects the developer’s mastery of the possibility of future change of requirements. A good designer can think of the possible changes of requirements in the future when he sees the requirements. The essence of using design space is that developers are not considerate or compromise for other reasons, or the example shown in Figure 3. If I knew at that time that there might be different ways to find users according to their roles, I would directly give the permission to “query users by part of their student / job number” in the design. When using it, I just need to configure which role has this permission (that is, in the V5 framework) . Then, when requirements change, I don’t need to use design space.
We need to know that there is a time cost for R & D system. Even when the designer considers the possibility of future change of requirements, it is impossible to leave all the possibilities in the interface and design (time cost is not acceptable, development cost is not acceptable). Therefore, a design space can be left at this time. When the requirements change in the future, the purpose of modifying the requirements can be quickly achieved by releasing the design space directly.
If you are interested in this, you can leave a message for discussion. If there are many people who are interested, I will write about how to reserve and use the design space.