NET 应用架构指导 V2[9]

本章将会讲述在表现层的设计中的关键问题。帮助你理解在典型的分层应用架构中表现层是怎么杨的?通常包括什么?设计表现层会碰到的关键问题?你将会看到设计指导,推荐的设计步骤,相关的设计模式,可以选择的技术。

  表现层组件的实现包括用来显示的用户接口,以及对于用户交互的管理。显示包括用户输入和显示的控件,还有管理用户的交互行为。下图中的粗黑线框中的内容就是表现层。

  

  表现层通常包括下面的部分:

 

  •   UI组件。就是应用用来显示和接受用户输入的可视化元素。
  •   表现层的逻辑组件。表现逻辑是定义了逻辑行为和结构的代码,是独立于UI实现的。当实现了独立的表现模式,表现逻辑组件会包括Presenter、Presentation Model、ViewModel组件。表现层组件也可能会包含表现层的Model组件,封装了来自业务逻辑层的数据,或者是表现层的Entity组件,封装了方便表现层消费的业务逻辑和数据。

  通常的设计考虑

  在设计表现层的时候,你需要考虑很多关键的因素。可以参考下面的准则,确保你的设计满足应用的需求:

  •   选择合适的应用类型。应用的类型会影响你的表现层选择。明确你是否需要实现富客户端、web client,还是一个rich internet(RIA)应用。最好基于应用的需求,组织的需要,和基础设施的限制,做出选择。
  •   选择合适的UI技术。不同的应用类型提供了不同的开发表现层技术。每一种技术都有优点,都会影响你设计表现层。
  •   使用相关的模式。可以参考那些证明可以解决问题的模式。例如:MVP,MVC。
  •   分离关注点。使用专注的UI组件,集中于呈现、显示内容。使用专注的表现逻辑组件,管理用户交互的过程,可以保证你可以进行单元测试。
  •   坚持用户驱动设计。在设计表现层之前,先对用户进行了解。用户调查,采访,确保设计的表现层可以满足用户的需求。
  • Consider human interface guidelines。考虑人机交互,例如向导式的界面(不知道翻译的是否正确)

  特定的设计问题

  下面的设计中遇到的一些问题:

  •   Caching缓存
  •   Communication通信
  •   Composition容器
  •   Exception Management异常管理
  •   Navigation导航
  •   User Experience用户体验
  •   User Interface用户界面
  •   Validation验证

  Caching缓存

  缓存是提高应用性能和UI响应的最佳技术。你可以在表现层使用数据缓存,来优化数据查询,避免网络来回访问,避免不必要重复处理。可以参考下面的指导:

  选择合适的缓存位置,例如:内存或者是硬盘。如果你的应用部署在web服务器场,避免使用本地缓存需要同步数据的问题。通常来说,对于web和应用服务器场的部署,考虑使用事务资源管理例如SQL SERVER,或者是支持分布式缓存的产品,例如:Memcached,或者是微软的Velocity缓存技术。但是,如果单个服务器的变化不是关键的,或者是数据变化很慢,内存缓存可能是比较合适的。

  •   当使用内存缓存的时候,考虑将缓存的数据格式化一下,使用对象而不是数据库的原始格式。但是避免缓存易变化的数据,因为如果数据不断的变化,创建和获取数据的代价会超出使用缓存带来的好处。
  •   不要缓存敏感数据,除非你进行了加密。
  •   不要想着依赖于缓存的数据,它可能已经被移除了。同样,要考虑到缓存的数据已经失效了。例如:当进行一个业务处理的时候,你可能需要获取最新的数据应用到处理中,而不是使用缓存的数据。
  •   考虑缓存数据的授权。如果用户访问数据的角色不同,要针对用户角色对缓存授权。
  •   如果你是用多线程,确保对缓存的访问是线程安全的。

  Communication通信

  •   考虑使用异步操作,或者是多线程,避免在WinForm或者是WPF中需要长时间运行造成的UI阻塞。在ASP.NET中,考虑使用ajax实现异步请求。如果运行时间过长,给用户进度提示,同时允许用户取消等待。
  •   避免将UI呈现和UI处理混在一起。
  •   在使用消耗较大的调用的时候,例如调用webservice或者是查询数据库,需要考虑是分解为多次的调用,每次小数据量,还是用较少的次数,每次多获取一些数据。如果需要请求大量的数据来完成功能,考虑先获取需要的数据,然后通过隐藏的线程获取其他数据,或者是在用户需要的时候再获取其他数据。

  Composition容器

  如果表现层使用在运行的时候组成的独立的模块和视图,你的应用是否很容易开发和维护?UI容器模式在运行的时候创建视图和表现布局。这种模式帮助最小化代码和库的依赖,否则在依赖改变的时候,需要重新编译和部署。容器模式帮助你实现共享、重用、可代替的表现逻辑和视图。在设计的时候可以参考下面的原则:

  •   避免组件之间的依赖关系。例如:使用抽象模式。考虑使用在运行的时候依赖注入的模式。
  •   考虑使用模板。例如:使用模板视图模式来组成动态web页面,确保可重用和一致性。
  •   考虑用可重用的模块化部分来生成视图。例如:通过使用那些容易添加的可分离的模块,来解耦你的应用。
  •   和表现层通信的时候,考虑使用松散耦合的通信模式。降低组件的耦合,提高可测试性和灵活性。

  Exception Management异常管理

  设计一个集中的异常管理机制,以一种一致的方式来捕获和管理意外的异常。要考虑异常信息在逻辑层和物理层之间的传播,甚至是跨越可信边界的传播。可以参考下面的原则:

  向用户提供友好的错误提示信息,确保在错误提示、错误页面、日志文件、审计文件中没有暴露敏感信息。如果有可能的话,提供一致的状态,如果不行就终止它。

  确保异常信息的捕获,而不是在全局错误的地方才捕获,在异常发生之后释放资源和恢复状态。全局异常显示的是未处理的异常,未处理的异常表明系统处于不一致状态,可能需要关闭重新启动。

  区分系统异常和业务错误。在发生业务错误的时候,给用户有好的提示,允许用户重新尝试。发生系统异常的时候,显示有好的提示,记录日志,帮助查找解决问题。

  只捕获你可以处理的异常,在不必要的时候不使用自定义异常信息。不适用异常来控制应用逻辑。

  Navigation导航

  •   设计自己的导航策略,确保用户通过你的导航和页面很容易的导航,以便你将导航从表现UI和UI处理中分离出来。确保在应用中,导航链接的显示和控制是一致的,减少用户的疑惑,隐藏应用的复杂性。参考下面的原则:
  •   设计工具条和菜单,帮助用户找到UI提供的功能。
  •   考虑使用向导,以一种可以预料的方式实现导航,如果使用的话,需要考虑向导之间的状态保存。
  •   避免导航事件的重复处理,避免硬编码导航的路径。考虑使用Command模式处理从多个来源的请求。

  User Experience用户体验

  良好的用户体验会将可用的和不可用的应用区分开来。感觉到的表现要比实际表现更重要。例如:用户不想等很久,页面才加载好。换句话说,也许就是几毫秒的UI区别,都会感觉应用不好。考虑使用调查、可用性学习、统计、面对面的交流来了解用户到底需要什么,希望你的应用提供什么,用这些结果来设计一个高效的UI。可以参考下面的原则:

  •   不要设计过于复杂的界面。为每一个关键的用户场景提供一个清晰的路径,考虑使用颜色和动画吸引用户关注UI的改变,例如状态的改变。
  •   提供帮助和有益的错误提示,不要暴露敏感信息。
  •   如果需要长时间执行,不要阻塞用户UI。提供进度的提示,给用户取消的机会。
  •   考虑给用户提供灵活的、自定义UI的个性化操作。
  •   考虑支持本地化和全球化,即使在设计的初始阶段不是主要的关注点。

  User Interface用户界面

  设计一个合适的用户界面,支持需要的数据输入和验证。可以参考下面的原则:

  •   考虑使用分离的表现层模式。例如:MVP。使用模板提供一致的界面。避免过于复杂的布局。
  •   考虑使用表单的方式来实现收集格式化数据的功能,文档的方式来实现收集随意输入的数据,向导的方式来实现需要序列化、或者是流程性数据驱动功能。
  •   避免使用硬编码的字符串。
  •   开始你的应用的访问群体。再设计输入的时候考虑特殊的用户群体,例如:为看不见的人士提供文字输入,为视力不好的人士提供文字和输入框放大的功能,考虑用户在没有其他输入设备的时候,只是用键盘输入的功能。
  •   考虑不同的屏幕大小,不同类型的设备,手持设备,触摸屏。创建web应用的时候,考虑使用css来布局,将会提升性能和可维护性。

  Validation验证

  设计一个高效的数据输入和验证策略对于安全和正确操作来说是关键的。确保表现层具有输入验证,就好像业务逻辑层需要有逻辑验证一样。可以参考下面的原则:

  输入验证应该由表现层来处理。同时业务规则的验证应该有业务逻辑层来处理。但是,如果业务逻辑层和表现层在物理上是分离的,业务逻辑的验证应该被镜像到表现层中,提高可用性和响应。可以使用元数据或者是在两层中使用通用的验证组件来实现。

  在验证策略中要设计限制、拒绝、审查恶意输入。Investigate设计模式和第三方的类库可以帮助你实现验证。识别适合验证的业务规则,例如:传输限制,实现综合的验证,确保这些规则没有被妥协。

  确保你正确的处理了验证错误,避免在错误提示中暴露敏感信息。另外,确保日志记录了验证失败,帮助查找发现恶意的行为。

原文地址:https://www.cnblogs.com/Leo_wl/p/1748222.html