C# 使用Fluent API 创建自己的DSL(推荐)

DSL的作用是解决领域专家与软件开发人员之间的沟通问题。听起来很唬人,其实不是什么高深的东西,我们可以使用Fluent API 创建自己的DSL

DSL(Domain Specified Language)领域专用语言是描述特定领域问题的语言,听起来很唬人,其实不是什么高深的东西。看一下下面的代码:

using FlunetApiDemo;

var 张三 = "张三"
                .是学生()
                .身高(1.62M)
                .体重(48M);

Console.WriteLine(张三.BMI());
Console.WriteLine(张三.BMI状态());

这段代码根据学生的身高体重,计算BMI并判断状态(偏瘦、正常、超重还是肥胖),看到这里,各位同学可能已经发现问题了:学生有小学生、中学生和大学生,难道计算算法一样?男生女生的计算算法也一样?在这个问题中,各位都是领域专家,从我写的描述特定问题的代码中发现了问题,我需要对代码进行修改,增加年龄和性别因素。

从上面的例子可以看到DSL的作用:是解决领域专家与软件开发人员之间的沟通问题。领域专家通常不懂得编程,无法判断开发人员写的代码是否符合领域的要求,只能是等到软件编写完成,从软件运行表现出来的功能进行判断,而这时成本已经发生了,几个来回下来,进度超时,成本超支。DSL使用领域相关的术语编写,领域专家可以理解,而语言本身基于某种宿主语言,比如C#,可以编译运行,容易验证。所以恰当的DSL可以打通领域专家和开发人员之间的障碍,使软件的业务核心部分开发可靠并有效率。“可以执行”是DSL与需求阶段使用的伪语言或者带图示的自然语言最大的不同。在需求描述的时候,经常使用各种图示或者伪语言对业务进行描述,伪语言一般是一种类似的结构化语言,这种貌似语言的东西往往是很有害的,因为只是大概描述了过程,很多实现细节被忽略或者隐藏了。由于不是严格的编程语言,无法生成可执行的代码,所以也就无法验证对错。

结合上面的例子,我们看一下如何使用Fluent Api创建自己的DSL。其使用的技术实质上是实现现有类型的扩展,这需要我们1)声明一个static类,2)在类中使用static函数,3)使用this关键字修饰需要扩展的类型。上面的"张三".是学生(),“是学生”是字符串类型的一个扩展,返回的是自己定义的Student类型,这段代码如下:

namespace FlunetApiDemo
{
    public static class FluentExt
    {
        public static Student 是学生(this string  name)
        {
            return new Student { Name = name };
        }

        public static Student 身高(this Student student,decimal height)
        {
            student.Height = height;
            return student;
        }

        public static Student 体重(this Student student, decimal weight)
        {
            student.Weight = weight;
            return student;
        }

        public static decimal BMI(this Student student)
        {
            return student.Weight / student.Height / student.Height;
        }

        public static string BMI状态(this Student student)
        {
            var bmi=student.BMI();
            if (bmi > 24) return "肥胖";
            if (bmi > 21) return "超重";
            if (bmi < 15) return "偏瘦";
            return "正常";
        }
    }
}

在Student类中只定义关键属性:

namespace FlunetApiDemo
{
    public  class Student
    {
        public string Name { get; set; }=string.Empty;

        public decimal Height { get; set; } 

        public decimal Weight { get; set; }
        public override string ToString()
        {
            return Name;
        }
    }
}

怎么样,挺简单的吧。完整的代码上传到github: https://github.com/zhenl/FlunetApiDemo

最后的问题是代码中的中文问题,我的原则是怎么方便怎么来,通常我们编写程序时不主张使用中文作为变量或者方法名称,尽管现代编程语言的编译器很多已经不限于只支持ASCII码,但我们仍然无法确保在某些情况下不出现问题(比如如果将中文命名的方法映射为Web Api接口,不支持中文的客户端可能无法调用这个Api)。然而作为领域特定语言的DSL就不用有这个限制,DSL的主要目的就是沟通,如果必须用英文或者汉语拼音进行编写,效果就会大打折扣,更不用说很多领域都是中文为主的,这里不展开说了,举几个例子,“唐诗”、“宋词”、“元曲”估计翻成英语领域专家和程序员都看不懂。

到此这篇关于C# 使用Fluent API 创建自己的DSL的文章就介绍到这了,更多相关C#  Fluent API内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C#中设计、使用Fluent API

    我们经常使用的一些框架例如:EF,Automaper,NHibernate等都提供了非常优秀的Fluent API, 这样的API充分利用了VS的智能提示,而且写出来的代码非常整洁.我们如何在代码中也写出这种Fluent的代码呢,我这里介绍3总比较常用的模式,在这些模式上稍加改动或者修饰就可以变成实际项目中可以使用的API,当然如果没有设计API的需求,对我们理解其他框架的代码也是非常有帮助. 一.最简单且最实用的设计 这是最常见且最简单的设计,每个方法内部都返回return this; 这样整

  • C#中实现Fluent Interface的三种方法

    背景知识 Fluent Interface是一种通过连续的方法调用以完成特定逻辑处理的API实现方式,在代码中引入Fluent Interface不仅能够提高开发效率,而且在提高代码可读性上也有很大的帮助.从C# 3.0开始,随着扩展方法的引入,Fluent Interface也更多地被开发人员熟悉和使用.例如,当我们希望从一个整数列表中找出所有的偶数,并将这些偶数通过降序排列的方式添加到另一个列表中时,可以使用下面的代码: 复制代码 代码如下: i.Where(p => p % 2 == 0)

  • C# 使用Fluent API 创建自己的DSL(推荐)

    DSL的作用是解决领域专家与软件开发人员之间的沟通问题.听起来很唬人,其实不是什么高深的东西,我们可以使用Fluent API 创建自己的DSL DSL(Domain Specified Language)领域专用语言是描述特定领域问题的语言,听起来很唬人,其实不是什么高深的东西.看一下下面的代码: using FlunetApiDemo; var 张三 = "张三" .是学生() .身高(1.62M) .体重(48M); Console.WriteLine(张三.BMI()); Co

  • FluentMybatis实现mybatis动态sql拼装和fluent api语法

    目录 开始第一个例子: Hello World 新建演示用的数据库结构 创建数据库表对应的Entity类 运行测试来见证Fluent Mybatis的神奇 配置spring bean定义 使用Junit4和Spring-test来执行测试 开始第一个例子: Hello World 新建Java工程,设置maven依赖 新建maven工程,设置项目编译级别为Java8及以上,引入fluent mybatis依赖包. <dependencies> <!-- 引入fluent-mybatis

  • Entity Framework使用DbModelBuilder API创建表结构

    DbContext类有一个OnModelCreating方法,它用于流利地配置领域类到数据库模式的映射.下面我们以fluent API的方式来定义映射.首先,先将Product类注释掉,重新编写该类,重新编写后的Product类: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace EFFluent

  • Entity Framework使用Fluent API配置案例

    一.配置主键 要显式将某个属性设置为主键,可使用 HasKey 方法.在以下示例中,使用了 HasKey 方法对 Product 类型配置 ProductId 主键. 1.新加Product类 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FluentAPI.Model { public cl

  • Python使用Windows API创建窗口示例【基于win32gui模块】

    本文实例讲述了Python使用Windows API创建窗口.分享给大家供大家参考,具体如下: 一.代码 # -*- coding:utf-8 -*- #! python3 import win32gui from win32con import * def WndProc(hwnd,msg,wParam,lParam): if msg == WM_PAINT: hdc,ps = win32gui.BeginPaint(hwnd) rect = win32gui.GetClientRect(hw

  • php的api数据接口书写实例(推荐)

    以下是接口代码实例: <?php $output = array(); $a = @$_GET['a'] ? $_GET['a'] : ''; $uid = @$_GET['uid'] ? $_GET['uid'] : 0; if (empty($a)) { $output = array('data'=>NULL, 'info'=>'坑爹啊!', 'code'=>-201); exit(json_encode($output)); } //走接口 if ($a == 'get_u

  • 使用FileReader API创建Vue文件阅读器组件

    有时候我们需要从文件中读取数据.在以前,你需要将其发送到服务器,然后返回所需的数据.问题是,现在我们还可以使用 FileReader API 直接访问浏览器中的文件. 如果我们只是想读取一个文本文件,以便在UI级别上做一些无关紧要的事情,那么就不需要将文件发送到服务器.下面的示例将实现从一个文件中读取相关的数据填充到一个 textarea 中. FileReader API FileReader API提供了一个很好的接口,可以使用文本或Blob对象类型以不同的方式读取数据. FileReade

  • 详解Go语言RESTful JSON API创建

    RESTful API在Web项目开发中广泛使用,本文针对Go语言如何一步步实现RESTful JSON API进行讲解, 另外也会涉及到RESTful设计方面的话题. 也许我们之前有使用过各种各样的API, 当我们遇到设计很糟糕的API的时候,简直感觉崩溃至极.希望通过本文之后,能对设计良好的RESTful API有一个初步认识. JSON API是什么? JSON之前,很多网站都通过XML进行数据交换.如果在使用过XML之后,再接触JSON, 毫无疑问,你会觉得世界多么美好.这里不深入JSO

  • 使用图灵api创建微信聊天机器人

    需要准备的资源: 图灵机器人账号 微信公共账号 点击访问 图灵机器人官网,快快注册,拥有自己的聊天机器人,可以在这里先体验一下 今天主要简述微信公共平台聊天机器人的搭建,首先需要注册微信公共账号,之后在图灵机器人网站上登录你的图灵账号,可以看到如截图所示的界面,在"机器人设定"界面可以进行机器人昵称.年龄.性别等信息的设定,在"机器人调教"界面可以教你的机器人回答特定问题,"知识库"可以导入知识库,增加你的机器人的能力~~~ 红色圈起来的部分是需

随机推荐