For detailed descriptions, refer to Paul Graham's Programming Bottom-Up top-down design from top to Bottom: the traditional method, the initial requirements are segmented step by step, to the final implementation of the granularity. Bottom-up design bottom-up: Many library functions and basic components are created in the original language environment, and these library functions and basic components are used to build the application system. Just like using the original tools to build a variety of building blocks and building houses of various shapes.
Top-down is a decomposition policy, while bottom-up is a composition policy.
Advantages of top-down: simple, decomposition is the specialty of human thinking; delays construction of details, and encapsulates harassment of detailed changes in the class architecture in advance; early identification of functions, overall organization.
Top-dowm disadvantage: The underlying complexity may not be carefully considered at the beginning.
Bottom-up advantage: Taking into account the underlying complexity earlier, it is conducive to the design of better high-level components and the universality of underlying components.
Bottom-up is weak: for human thinking, it is difficult to abstract from the bottom layer; the bottom layer parts may not be suitable for high-level components; the complexity of the bottom layer may overwhelm the design process.
Most of the time, we use both methods at the same time. At the beginning of a project, we will adopt a top-down approach. individuals and teams will always accumulate many of their own class libraries, components, tools, and frameworks, it can be applied to projects at any time. Many companies have dedicated teams to take charge of these tasks, which are a bottom-up approach.
It is not to say that the reuse of several components is called a bottom-up design. The bottom-up design idea strives to make the code to achieve the requirements as concise and concise as possible, the continuous expansion and improvement of tools and components at different levels is the core.
Mini-languages ages (little language)For more information, see Eric Raymond's Minilanguages.
The idea of Unix-style mini-programming ages is the same as that of bottom-up. However, Paul Graham's lisp back-up provides support at the language level, unix is a way of thinking and development around C.
Eric Raymond mentioned a scenario, that is, the bug rate of every hundred rows (as if we often use the bug rate of thousands of rows because of our high productivity ?), A requirement may require 1000 lines of code to be implemented in the original language, and dozens of lines may be required with the support of tools and class libraries. The direct effect is that the Code is short and easier to read, this can reduce bugs and improve code quality.
Refer to Eric Raymond's classification of languages
Taxonomy of different ages, we can see that he classified regexps, Yacc, Lex, make, XSLT, PostScript, and so on into mini
Language scope, because they are dedicated solutions for specific fields.
Eric Raymond mentioned three methods or effort directions to implement pocket languages. The two methods are correct. The last one is false:
1. Increase the description of a program problem to a level, which is more accurate and readable than the description of a common language.
2. Make the code closer to a brief description of the problem in a specific field, just like a simple language. However, note that the underlying Code encapsulates a complex data structure, rather than a control process. The control process should be determined by the user rather than the underlying implicit agent.
3. Build a mini language based on the original extension. Due to the continuous addition of patches and features, it will lead to implicit processes and mixed data structures without knowing the complexity, thus losing the meaning of the pocket. The correct approach is to redesign and review.FluentInterfaceFor details, refer to the FluentInterface of Martin Fowler to create an order. The general practice may be as follows: private void makeNormal (Customer customer Customer)
Order o1 = new Order ();
Customer. addOrder (o1 );
OrderLine line1 = new OrderLine (6, Product. find ("TAL "));
O1.addLine (line1 );
OrderLine line2 = new OrderLine (5, Product. find ("HPK "));
O1.addLine (line2 );
OrderLine line3 = new OrderLine (3, Product. find ("LGV "));
O1.addLine (line3 );
Line2.setSkippable (true );
O1.setRush (true );
FluentInterface refers to the following style: private void makeFluent (Customer customer)
Customer. newOrder ()
. With (6, "TAL ")
. With (5, "HPK"). skippable ()
. With (3, "LGV ")
. PriorityRush ();
The code in this form is short and clear, and the meaning of the expression is clear. Even domain experts can understand that Martin Fowler classifies this form as an Internal DSL, and whether the interface is fluent is also based on the DSL quality. The key is to take into account the context environment in which these methods are used to determine the returned type. For example, in the above example, The with () method is to add an order line project and add it to the order. An intuitive way is to return the newly created order line project object, however, in this context, it returns the order object.
Martin mentioned a problem, such as the method name and return type design. It is meaningful and smooth in the context in which the method is used, but it may not make sense for the object itself, difficult to understand (because it is out of the context ). Martin also mentioned that this method is not widely used at present, and its advantages and disadvantages need to be tested and verified. Eric Evans mentioned that it is more convenient to use this method on value objects. For the above example, we can imagine that if the with () method requires that the order line project object be returned in some context environments to make the context fluent, there will be a conflict. Eric
Evans's statement is self-evident. Let's take a look at examples in actual use, such as the IQuery and ICriteria interfaces in nhib.pdf, as well as many objects such as SqlString in it, and examples of JMock, it is only used on value objects and service objects. In terms of mini-language and bottom-up, it is sufficient to apply a specific domain. A solution is always unlikely to be applicable to a general domain, or the complexity will be more than the advantages of the method itself and become invalid.
Piers Cawley's Fluent Interfaces also talked about his ideas and how to write some content about Fluent interfaces.
For more information, see Arie van Deursen's Domain-Specific Languages: Annotated Bibliography.
DSL has not been formally defined, Arie van
Deursen is defined as follows: a domain-specific language (DSL) is a programming language or an executable standard language, through appropriate abstract symbols, it is also limited to providing a strong description for specific problem domains. DSL is usually relatively small and has only limited abstract symbols, so it is also called micro-ages or little
Languages, but has powerful descriptive capabilities for specific problem domains. 4GL for business data processing systems will be the result of all-round development of DSL.
Development Process: subfunction Library (
)-> Object-oriented framework and Component Framework (Object-oriented)
Frameworks, component frameworks)-> DSL.
DSL design method:
1. Confirm the problem domain
2. Collect knowledge about problem domains
3. extract knowledge into a certain number of semantic symbols and operations
4. Design a DSL that can briefly describe the application in the problem domain
5. Create a library to implement semantic symbols
6. Design and implement a compiler to convert the DSL program into a series of library calls
7. Compile a program using DSL
DSL implementation method:
1. explain or compile. The cost of developing a compiler or interpreter from scratch may be too high. You can also extend it to the basic language, that is, the following three methods.
2. Embedded language (Embedded
Languages) or domain-specific libraries. Implement components and Libraries (that is, user-defined syntax) targeting specific problem domains based on the basic language functions ). The advantage is that the compiler and interpreter of the basic language are reused. The disadvantage is that the DSL table power is insufficient due to the limitations of the basic language.
3. Preprocessing or macro processing. That is, code generation, script, and macro technologies are used. The advantage is that static checks and optimization are not performed at the domain layer. The error information feedback is also provided at the basic language layer during runtime.
4. extensible compiler or interpreter. That is, developing a general compiler or interpreter can be extended and applied to multiple other fields. The Tcl interpreter is a good example and has been extended and applied to many fields.
Arie van Deursen's article provides a lot of reference materials, through which you can fully understand all aspects of DSL.
Internal DSL, External DSLFor more information, see Martin.
DomainSpecificLanguage and DslBoundary of Fowler
It can be seen that Martin calls the 2 Embedded extensions ages or Libraries of the DSL implementation method mentioned above as Internal.
DSL, and other forms are called External DSL.
DSL classification is a very confusing thing. It is often just a conceptual difference. Martin explains the difference between Internal DSL and API in this article. External
The difference between DSL and GPL. In fact, on a platform like. Net, it is necessary to clearly distinguish between Internal DSL and External.
DSL is a little difficult, such as RegularExpression, XSLTransformation, and LINQ.
Fluent Interface is Internal
One form of DSL. Does nhib.pdf belong to Internal OR External? What about the self-developed OR framework? There is no need to explore the details.