Product or service

    On Habré (and in real IT life) there are many questions of the form:


    • Is it necessary to update the system (or dependencies in the application), if everything works like that?
    • Do I need tests (autotests) in the application (do you spend your time and customer’s money on them)?
    • Is there any point in the patterns and the selection of abstractions (after all, this spreads the code, reduces performance, etc.)?

    The key question in all the examples below is: what are you developing: a product or a service? Oddly enough, but as soon as you answer this question about goods and services, all doubts about the need for tests, abstractions, etc. will fall away by themselves.


    Terms


    They have a fundamental difference: the product is complete, it can be sold, and then forget about its existence. In the case of the service, the buyer and seller communicate for a long time (by analogy with a subscription, which is this very service).


    Product Examples:


    • The construction of the bridge. Actually, the bridge was built, commissioned (this is a fundamentally important step), the construction company forgot about it. In reality, there is still a guarantee for the construction, but for the sphericity of the experiment, it is better to pretend that it is absent (or very short). During the construction, it will be absolutely illogical to change plans in the process (for example, return the imported fence and buy another, more efficient one).
    • Sale stools. Everything is similar to a bridge, the most important thing is to sell this very stool. After that, the seller will forget about the buyer for a very long time (at least in most cases).
    • Sale of apartments (especially in the secondary market). Here again, the most important thing is to sell the apartment so that it does not fall apart in the first months. And what will happen next - the seller is absolutely unimportant.

    Examples of services:


    • Banking service. The client pays for the service once a month, the bank provides the service all this month. The client and the bank remember each other for at least the whole month, and often several years. It makes no sense to sell illiquid assets, because the client will refuse to service quite quickly.
    • Taxi service (i.e. Yandex Taxes, Gett, etc.). Despite the fact that trips are completed, companies make the bulk of their money on regular customers, on those who return. Therefore, it makes no sense to deceive the buyer in the first purchase (in the style of bombing), since the relationship here is long.
    • Supermarket. Again, the duration of communication between the seller and the buyer is much more important to us than momentary benefits. And this means that instead of selling spoiled bread, it is more profitable for the store to utilize the batch. Otherwise, the buyer will buy bread for the last time and will not come to the store at all. Moreover, unlike the example with the bridge, it is absolutely normal for the supermarket to conduct “refactoring” - an analysis of how efficiently the racks are efficient, etc.

    Why do we need to know the difference between a product and a service?


    The idea is simple: if you consider your program as a product (that is, your connection with it will break after the first release), then there is no point in wasting extra time neither on tests, nor on refactorings, nor on compliance with coding styles . After all, if you spend your time and do it "perfectly", then your product simply rises in price. And in the future, these abstractions will simply not be needed for you (after all, you should stop working on the program).


    However, if you provide a service for users (for example, you make an analogue of Facebook), then you will have tasks for updating dependencies, you will have tasks for adding / removing functions, and therefore there will still be tests, because they will reduce risks in the long term. Moreover, you will need to highlight abstractions, at least in order to embed new logic in the future. So, if you consider your development as a service, then you need to update dependencies, write tests, highlight abstractions and do a lot of other work to avoid legacy and minimize the risks of errors in the future.


    Manual: how to make a legacy program with your own hands


    In the context of this article, it is very easy to derive a formula for how you can very easily make legacy from almost any software being developed, and following this formula, the developer of this program itself will succeed without any help. The formula is simple: to get legacy software, you need to treat the development of service software as if you were making a product .


    Or in other words: if you see that you are participating in the development of a service (that is, you will be in this project for a long time, you will add new functions to the project for several years, adapt it to new realities), however, there is a desire to make the project truly legacy (then there is a program that is incredibly difficult to make changes that is unable to work on a newer OS / hardware, etc.), then just start treating the project as a product. Just consider each release as the last. Use the words "well, sold the version" more often. Make small crutches and hacks as active as possible, instead of processing the code. And finally: more manual labor (forget about TeamCity / Jenkins), and never write documentation, specifications, or various comments in code.


    It is quite interesting that if you literally slightly change the attitude towards software, then it itself will become a terrible legacy, moreover, made by yourself.


    Benefit: how not to make legacy out of your programs


    Oddly enough, however, in order not to get terrible software on hand, you just need to ask yourself a question once a month / quarter: and the product that I make is a product or service? And remember / write this answer at least for a while. In the future, any questions about tests, refactoring, documentation, etc. will disappear by themselves.


    Examples:


    • What should we do with tests that constantly crash with every dependency update and every release? And they fall not on business.
      • For a product program: it’s better to simply remove these problem tests. All the same, they now have more problems than benefits. And in the future, nobody will need them.
      • For a service program: it makes sense to repair / fix tests in order to reduce their false-positive response. Each repair of tests is our time, however, the presence of these tests will reduce the risk of missing an error in the future.
    • Should I upgrade to Spring Boot 2 , or does it make sense to stay on 1.5?
      • For the product program: strictly not. We will finish the project soon and will never return to this customer. We will have no task of supporting this program, nor of adding new features, nor of updating to a new Java with security fixes.
      • For the service program: strictly yes. After all, this version will be unsupported in a year . Moreover, in order to run in free Java, we will need to upgrade to Java 11 very soon, however, a number of modules from Spring Boot 1. * (at least ASM) does not support Java 9+ bytecode.
    • Should we update the technical documentation for the product?
      • For the product program: is it paid to us? If not, it’s better to delete it altogether, as it may contain errors that will then have to be fixed “under warranty”. And if there is no documentation, then there are no errors.
      • For the service program: of course yes. After a couple of years, this documentation will be very useful to us when new developers have to explain how and why everything works for us like that.

    A product or service is sold by an IT outsourcer


    Despite the fact that the outsourcer is technically an IT company (moreover, the main part of the track record is people related to IT), the most important steps in the project:


    • Contract signed with customer
    • The customer signed the "acceptance certificate" (or in another way - the finished goods are sold)

    That is, all other actions of the company’s employees revolve only around these points. And it is precisely these two things that directly affect what the outsourcer is developing - a product or service.


    For example, goods are often developed for government orders. And never services (although this also happens). And therefore, in such projects there is no reason to make documentation, speed up the program (that is, make the customer happy). So we get the rule: if you develop, test or configure software in an outsourcer company, who forgets about the contract after signing the act, then there is no point even thinking about tests, documentation, highlighting abstractions, etc.. Moreover, if you advise the middle manager to “make software better,” he will absolutely not understand why you are thinking about this in principle. After all, a company not only does not get any profit from refactoring, it can often incur quite real losses because the developer spends time do not understand what.


    Moreover, if an outsourcing company makes such software to order, then it often has no incentive to make programs safe (because in the future you can always just go to a blogger , as you did in the 90s, right? And the customer will incur all losses in one way or another )


    So why legacy?


    After reading the article, an idea involuntarily arises: after all, all these ideas are painfully simple. Why then do we get legacy software? Why does one company / team have products that are easy to support, while others have programs that slow down, and developers spend a lot of time on support?


    One (of many) answers is the attitude of the people in the teams to programs as a product, or as a service. Moreover, it is important to understand that in this context, a team is all the people who were involved in software development, that is, testers, developers, analysts, and management. The total position of all people gives the position of the team. And it can be like “we sell goods” or “we do service”.


    Examples of conflict when a team develops a service, but treats it like a product:


    • If the project participants are not interested in long work with this project. For example, a person may plan to leave the company in the near future. Or the company has a high turnover (including when people often move from team to team), which leads to the fact that project participants may not associate themselves with this project. Those. if you know that in six months it will work with other people and on other tasks, then what's the point of investing in the current program? Why write documentation, why do auto tests, etc.? It’s better to just make it faster, get a bonus for an accelerated five-year plan and go to work elsewhere.
    • The carrot and stick method in the team / company is built in such a way that it is much more profitable to report more often on the creation of new products and on replacing old ones. This can happen if all bonuses in the company are issued for the fact that “product A was made” or for “product B was redone”, and not for the fact that “product C is constantly evolving and helps to make money.” In this case, all reasonable people will avoid long periods (for this they will not give a carrot). The key difference is that in the presentation, the finished forms of the verbs will be prevalued in relation to the projects (i.e. the program is done , the project is completed ), instead of long ones (the service allows you to earn money, the team provides the infrastructure).
    • And do not forget about standard sabotage (or job security ) - why make documentation for a product that you know well? After all, otherwise the manager will easily find you a replacement. Why make life easier with software support? After all, if the software support is very simple, then you can be replaced by someone else. This point is very intersected with the first, which described a company with a large turnover. However, it is worthwhile to understand that the conditional "job security" has little in common with the idea of ​​goods or services, it’s just that this is often a good explanation of many processes, so one can not help but mention.

    Examples of the reverse conflict, when the team actually creates a product, but treats it as a service:


    • Misunderstanding of the business. Even a very honest outsourcer rarely admits that his profit is the difference between how much the customer pays for the project and how much it can cost in minimal execution, provided that the customer is ready to accept it. That is, the main income is an opportunity to save where it would be unreasonable to save in the long run. This is where the conflict arises - if the middle manager tells the customer that "we are doing the best software in the world", then the developer can begin to take it all at face value.
    • They always did that. If the team of enterprise java developers (who make services, which are then improved and supplemented for a decade) is given the task "to make a temporary service for copying files from point A to point B", then there is a good chance that this simplest service will be overcomplicated. Yes, it will copy files, but copying itself will be hidden behind 10 layers of abstraction (and after a couple of months - for 11th ).

    The impact of goods and services on languages ​​and technologies


    On a habr there is often a lot of debate as to which programming language is better. Or which technology is better. Oddly enough, many of them arise due to the fact that the parties have a different understanding of what the program is - a product or service.


    If you have a one-time task (for example, copying files from point A to point B with some conditions and minimal conversions), then it would be rather silly to choose technologies that are designed for long support, giving long backward compatibility. For such tasks, Go / Python would be the perfect solution.


    And vice versa - if your task is to provide a long service (with frequent security updates, etc.), then such advantages of the platform as backward compatibility, ease of updating, ease of patching, etc. come in first place. It already becomes completely unimportant to you whether it is easy or difficult to write Hello World in your chosen language, since such programs will be created once every several years.


    And how to use it?


    In conclusion - how to use the fact that the program can be both a product and a service.


    1. Once a month, just remember what you are doing: a product or a service.
    2. Do not try to develop a product. They sell it once and forget it. This approach is incredibly understandable to business. Work on the "made - forgot" system.
    3. Do not treat service projects as goods. You will communicate with users for a long time, in this case long-term cooperation is more important to them, rather than momentary benefits.

    Also popular now: