Java API 设计清单

为什么80%的码农都做不了架构师?>>>   hot3.png

在设计Java API的时候总是有很多不同的规范和考量。与任何复杂的事物一样,这项工作往往就是在考验我们思考的缜密程度。就像飞行员起飞前的检查清单,这张清单将帮助软件设计者在设计Java API的过程中回忆起那些明确的或者不明确的规范。本文也可以看作为“API设计指南”这篇文章的附录。

我们还准备了一些前后比对的例子来展示这个列表如何帮助你理清设计需求,找出错误,识别糟糕的设计实践以及如何寻找改进的时机。

这个清单使用了如下的语言规范:

要 – 表示必要的设计

建议 – 表示在几个最好的设计中选择一个

考虑 – 表示一个可能的设计上的改进

避免 – 表示一个设计上的缺陷

不要 – 表示一个设计上的错误

1. 包设计清单

1.1. 共通

▲1.1.1. 建议把API和实现放入不同的包

▲1.1.2. 建议把API放进上层包,而把实现放进下层包

▲1.1.3. strong>考虑把一组大型的API分拆进不同的包

▲1.1.4. 考虑把API和实现打包进不同的jar包

▲1.1.5. 避免API的实现类之间的内部依赖

▲1.1.6. 避免把API分拆了太细

▲1.1.7. 避免把公共实现类放到API的包中

▲1.1.8. 不要在调用者和实现类之间建立依赖

▲1.1.9. 不要把没有关系的API放进同一个包

▲1.1.10. 不要把API和SPI(service provider interface)放进一个包(注:两者不同可以查看这个页面http://stackoverflow.com/questions/2954372/difference-between-spi-and-api)

▲1.1.11. 不要移动或者重命名一个已经发布的公共API

1.2. 命名

▲1.2.1. (一级)包名以公司(或者组织)的根命名空间来命名

▲1.2.2. 使用一个稳定的产品名称或者一个产品系列的名称作为包的二级名称

▲1.2.3. 使用API名称作为包名的(三级名称)结尾

▲1.2.4. 考虑把仅包含实现的包的名称中包含”internal”这个词(注:似乎“impl”更常见一些)

▲1.2.5. 避免使用组合起来的名称

▲1.2.6. 避免包名和包内的类名使用同样的名称

▲1.2.7. 避免在包名称中使用“api”这个词

▲1.2.8. 不要使用营销,计划,组织单元(部门)和地理名称

▲1.2.9. 不要在包名中使用大写字母

1.3. 文档

▲1.3.1. 为每一个包提供一个package.html

▲1.3.2. 遵循标准的javadoc的规范

▲1.3.3. 在API的开始处用一句短小的话来概括(描述)

▲1.3.4. 提供足够多的细节来帮助判断是否需要使用和如何使用该API

▲1.3.5. 指出该API的入口(主要的类或者方法)

▲1.3.6. 包含覆盖主要的,基本功能演示的样例代码

▲1.3.7. 包含一个指向开发者指南的超链接

▲1.3.8. 包含一个指向手册的超链接

▲1.3.9. 指出相关的API集合

▲1.3.10. 包含API的版本号

▲1.3.11. 用@deprecated标记出不再使用的API版本

▲1.3.12. 考虑添加一个版权声明

▲1.3.13. 避免过长的包概述

▲1.3.14. 不要在发布的javadoc中包含实现相关的包

2. 类型设计清单(这里的“类型”个人理解为一组Api)

2.1. 共通

▲2.1.1. 确保每种(设计的)类型都有单一明确的目的

▲2.1.2. 确保每种类型代表了(业务)领域的概念,而不是为了(技术上)的抽象

▲2.1.3. 限制类型的总数量

▲2.1.4. 限制类型的大小

▲2.1.5. 设计相关的类型时保持和原有的类型的一致性

▲2.1.6. 建议为多种public的类型提供多种(private)的实现

▲2.1.7. 建议接口的实现类和继承关系的类应该在行为上保持一致性

▲2.1.8. 建议用抽象类而不是接口解耦Api的实现

▲2.1.9. 建议使用枚举而不是常量

▲2.1.10. 考虑使用泛型

▲2.1.11. 考虑在泛型参数上增加约束

▲2.1.12. 考虑使用接口来实现多继承的效果

▲2.1.13. 避免为使用者的扩展(需求)进行设计

▲2.1.14. 避免深度的继承层次

▲2.1.15. 不要使用public内嵌的类型

▲2.1.16. 不要申明public和protected的变量

▲2.1.17. 不要把实现的继承关系暴露给使用者

2.2. 命名

▲2.2.1. 使用名词或者名词词组

▲2.2.2. 使用PascalCasing(驼峰命名法的别称详见http://en.wikipedia.org/wiki/CamelCase)

▲2.2.3. 缩写仅第一个首字母大写

▲2.2.4. 为类型的实际作用使用精确的名称命名

▲2.2.5. 为最常用的类型准备最短最容易记忆的名称

▲2.2.6. 所有异常都以“Exception”结尾

▲2.2.7. 使用名词的单数(比如用Color而不用Colors)来命名枚举类型

▲2.2.8. 考虑较长的名称

▲2.2.9. 考虑派生类用基类的名称结尾

▲2.2.10. 考虑为抽象类名称使用“Abstract”开头

▲2.2.11. 避免使用缩略语

▲2.2.12. 避免太通用的名词

▲2.2.13. 避免同义词

▲2.2.14. 避免在相关的Api中使用类型的名称

▲2.2.15. 不要使用仅大小写不同的名称

▲2.2.16. 不要使用前缀

▲2.2.17. 不要以“I”作为接口的名称开头

▲2.2.18. 不要(重复)使用Java核心包中的名称

2.3. 类

▲2.3.1. 最小化实现使用的依赖

▲2.3.2. 先列出public方法

▲2.3.3. 申明实现方法为private(这里是笔误吗?)

▲2.3.4. 为一个public抽象类定义至少一个public的shi

▲2.3.5. 为基本的使用情况提供足够的缺省实现

▲2.3.6. 设计基本上不变的类

▲2.3.7. 把无状态,访问器,扩展(mutator个人理解为多种参数形式的方法)方法集合到一起

▲2.3.8. 把扩展方法的数量控制到最少

▲2.3.9. 考虑设计一个默认的无参的构造方法

▲2.3.10. 考虑重写equal,hashCode方法

▲2.3.11. 考虑实现Comparable接口

▲2.3.12. 考虑实现Serializable接口

▲2.3.13. 考虑使类可以容易的扩展

▲2.3.14. 考虑申明类为final

▲2.3.15. 考虑为类的实例化提供一个public的构造方法

▲2.3.16. 考虑使用自定义的类型来增强类的不可变性

▲2.3.17. 考虑设计不可变的类

▲2.3.18. 避免静态类

▲2.3.19. 避免使用Cloneable

▲2.3.20. 不要向静态类中添加实例duixi

▲2.3.21. 不要为使用者不应扩展的public抽象类提供public的构造方法

▲2.3.22. 不要滥用初始化

2.4. 接口

▲2.4.1. 为每一个public接口提供至少一个实现类

▲2.4.2. 为每一个public接口设计至少一个消费方法

▲2.4.3. 不要对一个已经发布的public接口添加新的方法

▲2.4.4. 不要使用标记接口(标记接口详见http://en.wikipedia.org/wiki/Marker_interface_pattern)

▲2.4.5. 不要把public接口设计成常量的容器(这个实在很常见啊……)

2.5. 枚举

▲2.5.1. 考虑为枚举类型指定一个0值(“NONE”或者“Unspecialized”等等)

▲2.5.2. 避免只有一个值的枚举

▲2.5.3. 不要使用枚举实现开放式的值集合

▲2.5.4. 不要为将来可能增加的值设计枚举

▲2.5.5. 不要为已经发布的版本增加新的枚举值

 

2.6. 异常

▲2.6.1. 确保自定义的异常可以被序列化

▲2.6.2. 考虑为每种类型定义一个不同的异常

▲2.6.3. 考虑为代码访问提供更多的异常信息

▲2.6.4. 避免深层的异常继承

▲2.6.5. 不要从Exception和RuntimeException以外的类派生自定义异常

▲2.6.6. 不要直接从Throwable派生异常

▲2.6.7. 不要在异常信息内包含敏感信息

2.7. 文档

▲2.7.1. 为每种类型(的Api)配上概述

▲2.7.2. 遵循标准Javadoc的约定

▲2.7.3. 每种类型开头以一句短小的话概述

▲2.7.4. 为是否使用以及如何使用该类型提供足够的细节来帮助做决定

▲2.7.5. 解释如何实例化一个类型

▲2.7.6. 为一个类型的主要的使用情景提供样例代码

▲2.7.7. 包含指向到开发指南的链接

▲2.7.8. 包含指向手册的链接

▲2.7.9. 显示相关的类型

▲2.7.10. @deprecated标签申明过时的类型

▲2.7.11. 文档类具有不可变性

▲2.7.12. 避免冗长的类概述

▲2.7.13. 不要为私有方法生成Javadoc

3. 方法设计清单

3.1. 共通

▲3.1.1. 确保每个方法实现一个目的

▲3.1.2. 确保相关的方法都是一个粒度级别的

▲3.1.3. 确保没有混合调用方法的公共代码

▲3.1.4. 使所有方法的调用具有原子性(原子性:http://jiangyongyuan.iteye.com/blog/364010)

▲3.1.5. 设计protected方法时要像public方法一样慎重

▲3.1.6. 限制扩展方法的数量

▲3.1.7. 设计扩展方法需要具有较强的稳定性

▲3.1.8. 建议为一系列重载的方法设计一个泛型的方法

▲3.1.9. 考虑使用泛型方法

▲3.1.10. 考虑设计方法对,即两个方法的作用是相反的

▲3.1.11. 避免“helper”方法

▲3.1.12. 避免长时间执行的方法

▲3.1.13. 避免调用者在普通使用中需要手动写循环

▲3.1.14. 避免可选的参数影响方法的行为

▲3.1.15. 避免不可重复调用的方法

▲3.1.16. 不要删除一个已经发布的方法

▲3.1.17. 不要在没有提供替换方法前把一个已经发布的方法标记为过时

▲3.1.18. 不要修改一个已经发布的方法的签名

▲3.1.19. 不要修改一个已经发布的方法的可观测行为(也许指的是输出之类)

▲3.1.20. 不要增加一个已经发布方法的调用条件

▲3.1.21. 不要减少一个已经发布方法的调用结果

▲3.1.22. 不要为已经发布的public接口新增方法

▲3.1.23. 不要为已经发布的Api新增重载

3.2. 命名

▲3.2.1. 用给力的,有表达力的动词作为名称起始

▲3.2.2. 使用驼峰命名法(好奇怪,前面写的是PascalNaming)

▲3.2.3. 为JavaBean的私有属性预留“get”“set”“is”等访问方法

▲3.2.4. 使用对调用者熟悉的词语

▲3.2.5. 尽量使用英语口语

▲3.2.6. 避免使用缩略语

▲3.2.7. 避免使用一般的动词

▲3.2.8. 避免同义词

▲3.2.9. 不要使用“黑话”

▲3.2.10. 不要依靠参数的名称和类型判断方法的意义

3.3. 参数

▲3.3.1. 为参数选择最合适的类型

▲3.3.2. 在相关方法的调用中对参数为null值的处理保持一致性

▲3.3.3. 在相关方法中参数的名称,类型和顺序需要保持一致

▲3.3.4. 在参数列表中把输出的参数放到输入参数之后

▲3.3.5. 为重载的方法省略常用的默认参数以提供一个较短的参数列表

▲3.3.6. 在无关的类型中为相同语义的操作提供重载方法

▲3.3.7. 建议使用接口而不是具体类作为参数

▲3.3.8. 建议使用集合而不是数组作为参数和返回值

▲3.3.9. 建议使用一般集合而不是原始(无类型)集合

▲3.3.10. 建议使用枚举而不是Boolean或者Integer作为参数

▲3.3.11. 建议把单个的参数放到集合或者数组参数之前

▲3.3.12. 建议把自定义类型的参数放大Java标准类型参数之前

▲3.3.13. 建议把对象类型的参数方法值类型的参数之前

▲3.3.14. 建议使用接口而不是具体类作为返回值

▲3.3.15. 建议把空的集合而不是null作为返回值

▲3.3.16. 建议把返回值设计成可以作为其他方法的合法输入参数

▲3.3.17. 考虑为不可变参数设计一个副本

▲3.3.18. 考虑在内部存储弱引用的对象

▲3.3.19. 避免参数数量变更

▲3.3.20. 避免参数长度太长(超过3个)

▲3.3.21. 避免连续的同类型的参数

▲3.3.22. 避免用作输出或者输入输出的参数

▲3.3.23. 避免方法重载

▲3.3.24. 避免参数类型暴露实现细节

▲3.3.25. 避免boolean参数

▲3.3.26. 避免返回null

▲3.3.27. 除了Java核心Api,避免把类型作为不相关的Api的返回值

▲3.3.28. 避免把可变的内部对象作为返回值来引用

▲3.3.29. 不要把预先设置的常量作为整型值参数使用

▲3.3.30. 不要为将来的(扩展设计)考虑预留参数

▲3.3.31. 不要在重载方法中改变参数的名称的顺序

3.4. 异常处理

▲3.4.1. 只有在异常情况下才抛出异常

▲3.4.2. 只需要为可恢复的错误抛出已确认的异常

▲3.4.3. 为了通知Api使用错误而抛出运行时异常

▲3.4.4. 在适当的抽象层次抛出异常

▲3.4.5. 进行运行时预置条件的检查

▲3.4.6. 为一个被不能为null的参数抛出空指针异常

▲3.4.7. 为一个除为null以外异常值的参数排除非法参数异常

▲3.4.8. 为一个错误上下文环境中的方法调用抛出非法状态异常

▲3.4.9. 在错误信息中显示出参数的预置条件

▲3.4.10. 确保失败的方法调用不会产生单向的后果

▲3.4.11. 为回调方法中的禁止使用的Api提供运行时检查

▲3.4.12. 建议优先使用Java标准异常

▲3.4.13. 建议提供抛出异常的条件的查询方法

3.5. 重写

▲3.5.1. 使用@Override注解

▲3.5.2. 维持或弱化预置条件

▲3.5.3. 维持或者加强后置条件(不好翻译,大概output+effect的意思)

▲3.5.4. 维持或者加强不可变性

▲3.5.5. 不要抛出新增的运行时异常

▲3.5.6. 不要更改方法的类型(无状态,访问器或者扩展方法等)

3.6. 构造方法

▲3.6.1. 最小化构造方法中的工作

▲3.6.2. 为所有的属性设置合理的默认值

▲3.6.3. 仅把构造方法的参数作为一种设置参数的快捷方法

▲3.6.4. 校验构造方法的参数

▲3.6.5. 以参数相应的属性为其命名

▲3.6.6. 当提供了多个构造方法时,遵循指南对其进行重载

▲3.6.7. 建议使用构造方法而不是静态的工厂方法

▲3.6.8. 考虑使用无参的构造方法

▲3.6.9. 如果不是总需要新的实例,考虑使用静态的工厂方法

▲3.6.10. 如果你需要在运行时决定一个合适的类型,考虑使用静态的工厂方法

▲3.6.11. 如果你需要访问外部的资源,考虑使用静态的工厂方法

▲3.6.12. 当面临非常多的参数的时候,考虑使用生成器(builder)

▲3.6.13. 当需要回避直接实例化类的时候使用考虑private的构造函数

▲3.6.14. 避免创建非必需的对象

▲3.6.15. 避免finalizer

▲3.6.16. 不要从无参的构造方法中抛出异常

▲3.6.17. 不要向一个已经发布的类中添加显示的构造方法

3.7. Setters和getters

▲3.7.1. 以get开头命名一个返回值不为boolean的访问属性的方法

▲3.7.2. 以is,can开头命名一个返回值为boolean的访问属性的方法

▲3.7.3. 以set开头命名一个更新本地变量的方法

▲3.7.4. 校验setter方法的参数

▲3.7.5. 最小化getter和setter方法的工作

▲3.7.6. 考虑从一个getter方法中返回不可变的集合

▲3.7.7. 考虑实现一个private接口的集合替代public的集合属性

▲3.7.8. 考虑只读的属性

▲3.7.9. 设置可变类型的属性时考虑Defensive Copy(Defensive Copy详见:http://www.javapractices.com/topic/TopicAction.doId=15)

▲3.7.10. 当返回可变类型的属性时考虑Defensive Copy

▲3.7.11. getter方法避免返回数组

▲3.7.12. 避免根据方法内信息无法完成的校验

▲3.7.13. 不要从getter方法中抛出异常

▲3.7.14. 不要设计只能set的属性方法(仅有public的setter而没有public的getter)

▲3.7.15. 不要依赖属性设置的顺序

3.8. 回调

▲3.8.1. 设计时使用最严密的预置条件

▲3.8.2. 设计时使用最弱的后置条件

▲3.8.3. 考虑传递引用对象的方法中把回调接口作为第一个参数

▲3.8.4. 避免有返回值的回调方法

3.9. 文档

▲3.9.1. 为每个方法提供Javadoc注释

▲3.9.2. 遵循标准的Javadoc约定

▲3.9.3. 每个方法以一句短小的话作为概述

▲3.9.4. 申明相关的方法

▲3.9.5. @deprecated标签申明过时的类型

▲3.9.6. 显示所有过时方法的替换方法

▲3.9.7. 避免冗长的zhus

▲3.9.8. 包含常用的使用模式

▲3.9.9. (如果允许的话)包含null值的确切含义

▲3.9.10. 包含方法的类型(无状态,访问器或者扩展)

▲3.9.11. 包含方法的预置条件

▲3.9.12. 包含算法实现的性能特征

▲3.9.13. 包含远程方法调用

▲3.9.14. 包含访问外部资源的方法

▲3.9.15. 包含哪些API可以在回调中使用

▲3.9.16. 考虑为了描述方法的行为而包含单元测试

转载于:https://my.oschina.net/jsan/blog/40277

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/548627.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利用FSMT进行文件服务器迁移及整合

当企业文件服务器(DFS、共享文件夹等)面临硬件更新、系统升级或文件服务器合并的情况时,往往会出现不确定的文件丢失、需要重新设置所有权限、无法将多个文件服务器集成到一台服务器上等问题,为了保证文件服务器的数据完整以及权限…

RHEL 6上KVM的安装配置及使用-将物理接口桥接到桥接器

作业环境服务器端操作系统:Red Hat Enterprise Linux Server release 6.0 (Santiago)KVM:qemu-kvm-0.12.1.2-2.113.el6.x86_64 客户端操作系统:Windows 7KVM管理工具:Xming 6.9 一、安装KVM及相关软件 1、KVM 需要有 CPU 的支持&a…

C#中IEnumerableT.Distinct()将指定实体类对象用Lambda表达式实现多条件去重

背景说明 在EF等ORM框架中需要以List实体类的方式对数据进行大量操作,其中免不了对一些数据进行去重复,而C#中IEnumerable.Distinct()便提供了这一功能。只是对刚开始接触的新人来说比价抽象难以接受,本文会对这一功能进行简要说明&#xff…

C#中利用Linq.Dynamic实现简单的动态表达式构建查询

背景介绍 在ADO.NET中我们可以根据用户输入的查询条件拼接出指定的SQL语句进行查询或者筛选出所需的数据,但是在ORM框架如EF中,我们一般用LINQ操作数据查询,LINQ是否可以像SQL一样拼接查询条件呢?答案是可以的。这一技术叫Linq.D…

C#中IEnumerableT.GroupBy()的简单使用

背景介绍 在实际项目中,对数据进行GroupBy肯定是常用需求之一,特别是采用EF等ORM框架后隔绝了用SQL语句直接操作数据,LINQ中的GroupBy肯定是要掌握的。 首先先对一个字段GroupBy,代码如下: static void Main(string[…

25 个精美的后台管理界面模板和布局

任何系统都会有一个管理后台,好看的管理后台看起来赏心悦目,管理的时候心情也舒畅,本文给大家推荐 25 个制作精美的后台管理界面的模板和布局,你值得拥有。 Free Admin Template Web App Theme Spring Time Free Admin Template F…

C#中IEnumerableT.Aggregate()的简单使用

背景介绍 IEnumerable<T>.Aggregate()在LINQ使用中好像很不起眼&#xff0c;但我个人认为这是十分实用并且强大的&#xff0c;支持自定义聚合操作&#xff0c;方法定义中的Func包含3个TSource参数&#xff0c;分别为下一个执行聚合的元素&#xff0c;当前聚合的元素&…

C#中IEnumerable.OfType()方法的简单使用

背景介绍 OfType的定义十分简单&#xff1a;IEnumerable.OfType(TResult)&#xff0c;如其定义&#xff0c;其中TRsult为所要过滤的类型。由于非泛型集合一律以Object类型存储对象&#xff0c;因此一个非泛型集合可能存储了各种类型&#xff0c;而OfType()方法可以轻松的对指定…

C#中IEnumerableT.Join()和IEnumerableT.GroupJoin()简单使用

背景介绍: 在无主外键关系的表中如果如果要关联就要用Join()和GroupJoin()方法了&#xff0c;我们先看Join()方法&#xff0c;代码如下&#xff1a; static void Main(string[] args) {List<SW_XSDD> sw_xsdd new List<SW_XSDD>(){new SW_XSDD { com_id "…

利用ASP.NET MVC 的默认类型绑定器---将Jquery datatables中的数据强类型绑定到实体类中

背景描述&#xff1a; 本文参考资料&#xff1a;https://blog.csdn.net/honantic/article/details/45913403 阅读了上述博文后对我产生了启发&#xff0c;在ASP.NET MVC 5中如何将大批量的数据比如说表格中的数据传到后台&#xff0c;是否可以像HTML辅助类一样强类型绑定实体…

JavaScript模态对话框类(拖拽时动画)

2010年写了一个模态对话框类&#xff0c;这次进行一些重构和扩充。拖拽时使其有动画效果。接口没变&#xff0c;如下 new ModelDialog({caption 标题 对话框标题(默认)template 主体内容 (默认)dialogCls 对话框className md-dialog(默认)headCls 头部classNa…

C#中其他简单LINQ查询表达式的简单使用介绍

本文主要记录下其他简单LINQ表达式&#xff0c;因为比较简单&#xff0c;记录下以后方便回忆&#xff0c;本文也会持续更新。 一些有用的LINQ扩展方法&#xff1a; LINQ表达式作用是否延迟查询Range生成指定范围内的整数的序列 Repeat生成包含一个重复值的序列 Skip跳过指定数…

支持上传文件的xhEditor for Typecho EX插件

2019独角兽企业重金招聘Python工程师标准>>> Typecho是一套超轻量的开源博客&#xff0c;界面简洁&#xff0c;功能紧凑&#xff0c;但是Typecho的文本编辑器实在是不好&#xff0c;需要自己写html代码&#xff0c;插图也不方便。试用了几个插件&#xff0c;发现Tin…

C#中IEnumerableT.Select()、SelectMany()的简单使用

本文主要用来记录、让自己有所了解和提升&#xff0c;以后遗忘时可以查看&#xff0c;关于SelectMany()&#xff0c;这篇文章写得不错&#xff0c;值得一看。 话不多说&#xff0c;先上代码看 Select() public class Person {public string Name { get; set; }public string G…

C#中合并两个lambda表达式

在LINQ中如何查询条件不固定&#xff0c;如何合并两个lambda表达式&#xff1f;其中一个方式是LINQ.Dynamic&#xff0c;关于LINQ.Dynamic的简单使用可以参考这篇文章&#xff0c;还有一种方法是利用Expression表达式树&#xff0c;有关表达式树的介绍&#xff0c;可以看这篇文…

彻底理解 Cookie、Session、Token

发展史 1、很久很久以前&#xff0c;Web 基本上就是文档的浏览而已&#xff0c; 既然是浏览&#xff0c;作为服务器&#xff0c; 不需要记录谁在某一段时间里都浏览了什么文档&#xff0c;每次请求都是一个新的HTTP协议&#xff0c; 就是请求加响应&#xff0c; 尤其是我不用记…

C#利用反射实现动态加载程序集简单案例

反射可以不但用来读取元数据&#xff0c;还可以使用反射从编译时还不清楚的类型中动态创建程序集&#xff0c;此案例摘自C#高级编程。 首先先创建一个控制台应用程序&#xff0c;然后添加一个类库&#xff0c;类库名称为CalculatorLib&#xff0c;如下图所示&#xff1a; Calcu…

设置与读取C#控制台应用程序Main函数中的参数args

在项目属性面版->调试->命令行参数设置。空格分隔。读取&#xff1a;string[] str Environment.GetCommandLineArgs();Main函数是C&#xff03;应用程序的入口点&#xff0c;Main函数可以有四种签名&#xff0c;分别如下:static void Main()static void Main(string[] a…

基于AgileEAS.NET企业应用平台实现基于SOA架构的应用整合方案-开篇

为什么80%的码农都做不了架构师&#xff1f;>>> 开篇 系统架构的文章&#xff0c;准备在这段时间好好的梳理和整理一下&#xff0c;然后发布基于AgileEAS.NET平台之上的企业级应用架构实践&#xff0c;结合具体的案例来说明AgileEAS.NET平 台之上如何进行系统的逻辑…