This post was last edited by Summer on 2017-9-27 15:32
This article is a short story that imitates Q&A, and the author uses a humorous style to briefly analyze the work that architects do: I want to be a software architect. This is a great option for young software developers. I want to lead the team and make important decisions about databases and frameworks, webservers, etc. Oh, then you don't want to be a software architect at all. Of course I wanted to be the maker of important decisions. That's fine, but you don't include important decisions in your list, which are irrelevant decisions. What do you mean? Are you saying that databases are not important decisions, do you know how much we spend on them? Maybe it costs too much. However, databases are not one of the important decisions. How can you say that? The database is the core of the system, where all data is systematized, classified, indexed, and accessed. Without a database, there would be no system. The database is just an IO device that happens to provide some useful tools for classification, querying, and information reporting, but these are only auxiliary functions of the system architecture. Assistance? This is outrageous. That's right, it's auxiliary. The business rules of the system may be able to take advantage of some of these tools, but those tools are not inherent to the corresponding business rules. If needed, you can replace the existing ones with different tools; And the business rules will not change. Well, yes, but it had to be re-coded, because these tools were used in the original database. That's your problem. What do you mean? Your problem is that you think business rules depend on database tools, but they are not. Or at least, it shouldn't be like this until a good architecture is provided. It's just crazy. How do you create business rules that don't use those tools? I'm not saying they don't use database tools, but they don't depend on it. Business rules don't need to know which database you're using. So how do you get business rules without knowing what tools to use? Invert the dependencies so that the database depends on business rules. Ensure that business rules are not dependent on the database. You're talking nonsense. On the contrary, I am using the language of software architecture. This is the principle of dependence inversion: low-level standards should rely on high-level standards. Nonsense! High-level criteria (assuming referring to business rules) Calling low-level criterions (assuming referring to databases). Therefore, the high-level criterion will rely on the low-level criterion according to the principle that the caller depends on the callee. Everyone knows this! This is true at runtime. But when compiling, what we want is dependency inversion. The source code of the high-level guidelines should not mention the source code of the low-level guidelines. Come on! How can you make a call without mentioning it? Of course no problem. That's what object-oriented is involved. Object-orientation is about real-world model creation, combining data, functionality, and cohesive objects. It's about organizing code into an intuitive structure. That's what they say? As we all know, this is the obvious truth. Yes, it is, however, when using object-oriented guidelines, it is indeed possible to invoke without mentioning it. Well, how to do that? In object-oriented design, objects send messages to each other. That's right, of course. When a sender sends a message, it doesn't know the type of receiver. It depends on the language used. In Java, the sender knows at least the base type of the receiver. In Ruby, the sender at least knows that the receiver is capable of handling the messages received. That's right. In any case, though, the sender does not know the specific type of receiver. That's right, well, it is. Therefore, a sender can design a receiver to perform a function without mentioning the specific type of receiver. That's right, that's right. I understand. However, the sender still depends on the receiver. This is true at runtime. However, it is different when compiled. The source code of the sender does not mention or depend on the source code of the receiver. In fact, the source code of the receiver depends on the source code of the sender. No way! The sender still depends on the class it sends. Perhaps from some source code, it will be clearer. The following paragraph is written in Java. First up is the sender: package sender; public class Sender { private Receiver receiver; public Sender (Receiver r) { receiver = r; } public void doSomething () { receiver.receiveThis (); } public interface Receiver { void receiveThis (); } }Here's the receiver: package receiver; import sender. Sender; public class SpecificReceiver implements Sender.Receiver { public void receiveThis () { //do something interesting. } }Note: Receiver depends on sender, SpecificReceiver depends on sender, and there is no receiver-related information in sender. yes, but you're lying, you put the receiver's interface in the sender class. You are starting to understand. What do you know? Of course, it is the principle of architecture. Sender has the interface that receiver must implement. If that means I have to use nested classes, then ...... Nested classes are just one of the means to an end, there are other ways. Well, wait a minute. What does this have to do with databases? We started talking about databases. Let's take a look at the code a little more. The first is a simple business rule: package businessRules; import entities. Something; public class BusinessRule { private BusinessRuleGateway gateway; public BusinessRule (BusinessRuleGateway gateway) { this.gateway = gateway; } public void execute (String id) { gateway.startTransaction (); Something thing = gateway.getSomething (id); thing.makeChanges (); gateway.saveSomething (thing); gateway.endTransaction (); } }Business rules don't have much weight. This is just one example. There could be more such classes that implement many different business rules. Okay, so what exactly is Gateway? It provides all data access methods through business rules. Implement it as follows: package businessRules; import entities. Something; public interface BusinessRuleGateway { Something getSomething (String id); void startTransaction (); void saveSomething (Something thing); void endTransaction (); }Note: This is in businessRules. Okay, what is the Something class? It represents a simple business object. I put it in entities. package entities; public class Something { public void makeChanges () { //... } }Ultimately the BusinessRuleGateway implementation, this class knows the real database: package database; import businessRules.BusinessRuleGateway; import entities. Something; public class MySqlBusinessRuleGateway implements BusinessRuleGateway { public Something getSomething (String id) { // use MySql to get a thing. } public void startTransaction () { // start MySql transaction } public void saveSomething (Something thing) { // save thing in MySql } public void endTransaction () { // end MySql transaction } }In addition, note that the business rules call the database at runtime; However, at compile time, the database involves and depends on businessRules. Well, I think I get it. You're just using polymorphism to hide the fact that the database is implemented from business rules. However, an interface is still needed to provide all the database tools to the business rules. No, not at all. We have not attempted to provide database tools to business rules. Instead, they use business rules to create interfaces for what they need. Implementing these interfaces allows you to call the right tools. Yes, but if you need to use every tool for all business rules, then just put the tool in the gateway interface. Ah, I don't think you still understand. Understand what? This is already clear. Each business rule defines only one interface for the data access tools it needs. Wait a minute, what do you say? This is the Interface Segregation Principle. Each business rule class uses only certain facilities of the database. Therefore, the interfaces provided by each business rule can only access the corresponding facilities. However, this means that there are many interfaces and many small implementation classes that call other database classes. Great, you are starting to understand. But it's too messy and a waste of time. Why do this? This is organized and saves time. Come on, get a lot of code for the sake of code. On the contrary, irrelevant decisions can be delayed through important architectural decisions. What does that mean? I remember at the beginning, you said you wanted to be a software architect, didn't you? You want to make all the decisions that really matter. yes, that's what I thought. You want to make decisions about databases, webservers, and frameworks, right? yes, you say that none of that matters. Just irrelevant content. That's right. That's it. The important decisions made by software architects are those that allow you to make decisions about databases, webservers, and frameworks. But you have to decide which ones first! No, it doesn't work. In fact, these can be decided later in the development cycle, when the information is more abundant. It is a disaster if architects identify frameworks in advance only to find that they do not provide the required performance or introduce intolerable constraints. Only when the architect decides to postpone the decision will he make a decision when the information is sufficient; Teams that do not use slow and resource-intensive IO devices and frameworks can create fast, lightweight test environments at the discretion of architects. Only its architects care about what really matters and delay those that don't, and such a team is the lucky one. Nonsense, I don't understand what you mean at all. Well, take a good look at this article, otherwise you will have to wait another 10 years to figure it out.
|