One of the most common practices in Software Engineering, when the mastery of the problem is complex, is the construction of a conceptual model. A conceptual model is the representation of the concepts and associations, typical of the real world, that we want to register through our software. For example, if we want to build software to record car rentals on a Kart's circuit (and we don't even know what Kart is), first, we should model the concepts involved ("Kart" and "User") and how they relate among them (a User "reserves" a Kart, etc.). Once we understand the domain, we can program it.
What is a domain that every software engineer knows is incredibly complex? Well, nothing more and nothing less than the world of any of the software engineering technologies. What tool can we use to better understand this complex domain and be able to program? The meta-models.
What is a Meta-model?
Let's imagine, for a moment, that we have to make software for a company that develops databases. Specifically, imagine that we are asked to implement software to help them detect problems in the designs of their SQL databases (such as foreign key cycles). What are the real world concepts that this company works with? Here we are no longer talking about "Users" or "Karts", but about much more abstract classes such as "SQL Table" and "SQL Attribute".
A meta-model is a representation of another model. For example, the following figure is a snippet of an SQL meta-model:
An instance of this meta-model would be an SQL schema. For example, an instance of "SQLTable" could be the SQL table "User" (with which we store users in the database).
From here, the problem of detecting foreign key cycles becomes a problem of traversing the meta-model associations. In fact, any problem analyzing code in a language (such as SQL or Java) can become a problem for traversing your meta-model.
Com es poden dur a la pràctica els meta-models?
Well, it's very easy, you only need two things:
- An implementation of the meta-model itself. That is, an implementation of their classes and associations
- A component responsible for instantiating the meta-model.
Following the example of SQL, we could implement, in Java, the classes of the previous meta-model (SQLTable classes, SQLAttribute, etc). Moreover, we could implement a parser, in Java, that reads "CREATE TABLE ..." statements to instantiate the tables, attributes, and foreign keys (described in the statement) as objects of the previous meta-model. From there, finding foreign key cycles becomes a problem of navigating our Java instances (which represent SQL concepts).
Note that when representing SQL concepts as Java classes, we have all the power of object orientation to make code extensible, maintainable, and reusable. In fact, you could reuse and extend the previous metamodel to make things more interesting (for example, rearrange "INSERT INTO ..." instructions on different tables so as not to violate foreign keys, or detect the spread of DELETE_ON_CASCADE between different tables, etc.) .
But none of this is limited to SQL. Similarly, we could do a JS parser in Java (or vice versa), to detect problems, patterns, or extract any information imaginable (in code). We can even make an analyzer of a language ... in the language itself!
If you are interested in the world of meta-models, you can see an implementation of a Java meta-model, made with Java, at https://javaparser.org/.