- 章节名：Part 1
- 2013-05-18 17:49:08
Domain separate into problem domain and solution domain. The problem domain is closed to business, while the solution domain map the implementation to problem domain. These 2 domain communicate with "domain vocabulary", which explain domain concepts to the outside world. DSL qualities: 1. specific problem area, 2. higher level of abstraction. DSL classify: + Internal DSL. Use the infrastructure of an existing programming language. + External DSL. Has separate infrastructure for lexical analysis, parsing techniques, interpretation, compilation and code generation. + Nontextual DSL. Some representation like graphic, etc. DSL Pros: expressive, concise, higher level of abstraction, higher payoff, scalable DSL Cons: hard design, upfront cost, performance(may be), lack adequate tool support(may be), Yet-Another-Language-To-Learn Syndrome(-_-#), language cacophony(using multiple DSLs). First, Create a domain vocabulary, Then, Implement the program domain. Builder design pattern help make published api more expressive.Fluent Interfaces provide an easy-to-read representation of remain problem.(See more design abstraction in Appendix A) Problems: Verbosity in syntax ( language basic syntax and design pattern details ) and Extra non-domain complexity. Solution: + Externalizing the domain with XML: It's more a documentary than an expressed-elegantly control structures. + Groovy. A dynamic language for JVM, that supports method_missing, meta programming, closure. Integrating DSL with core application using `new GroovyShell().evaluate(script)` Internal DSL: + Smart API is based on chaining method, also called fluent interface. Groovy or Ruby offer `named arguments` to help build Smart API. + Syntax Tree Manipulation. We can generate code by manipulating the AST. + Some Statically typed language( like Haskell, Scala) offer `types` to abstract domain semantics and make syntax more concisely, without using technique of generating codes. Pros: Have automatically type-checked by the host language compiler. + MetaProgramming! Runtime metaprogramming makes DSL dynamic by generating code during runtime. With compile-time metaprogramming, most common implemented with `Macros`, we can add custom syntax to DSL. External DSL: consists of 2 phases: `Parse` and `Process`. + Context-driven string manipulation: just a string that doesn't make sense in any programming language, but it can be coerced to valid Ruby or Groovy code. + XML configuration spec to a consumable resource: DI + DSL WorkBench. + Mix-in DSL with Embedded foreign code: let language parse the extension syntax using EBNF + DSL Design Based on Parser Combinator. Another way to define grammar . Choosing DSL Implementation: + Reusing Existing Infrastructure: Meta-Programming is often better than embedded variant. + Leveraging Existing knowledge: Your team members. + Learning curve with external DSLs. Hard, but you can customize almost everything. + The right level of expressivity. Internal DSL may cause abstraction leaky. + Composability. Composing the host language and internal DSL is easy. External DSLs is harder to make composaility. Internal DSL integration patterns + DSL wrapper: Implementation using java, and wrapped with Scala + Language-specific integration features: (GroovyClassLoader#run).delegate(SolutionDomainInstance) + Spring-Based integration: Under using Spring DI as interface, we can write ruby dsl. External DSL integration patterns: XML + Context-driven string manipulation: string convert to host language through tokenize process(re, dynamic eval) + Transforming XML to a consumable resource: XML parsers are the most natural form of integration point. + Non-textual representation: -> AST + Mixing DSL with embedded foreign code: transforms the DSL into appropriate data structures in the language of the embedded code and plugs in the embedded code snippets as callbacks. + DSL design-based on parser combinators: Parser combinators are implemented as a library in languages. Handle Errors and Exceptions: + Naming an exception: use domain vocabulary + Handling incorrect typing errors: use `method_missing` for internal DSL, report error occur line when parse error for external DSL. + Handling exceptional business conditions Managing performance: It's not so important.Even so, we need to consider performance factors when designing. Benchmark extensively before going for optimization.
大句哥哥对本书的所有笔记 · · · · · ·
Internal DSLs fall into two categories: Embedded(Smart API, Reflective, Typed embedded)...
说明 · · · · · ·