并不是所有人都需要看到所有的类型,因此我们创建的每一个类型也没有必要设置为public,我们应该为每个类型提供最低的可见性,只要能够达到目的就可以了。

Visual Studio中创建新的类型时,提供的默认可见性是internal,在程序集内是可见的。如果我们将类型声明为public,那么任何使用这个程序集的代码都可以访问这个类型,这样在今后的维护过程中,很可能会添加不必要的重复工作,因为类型的可见性越低,在以后更新时的修改工作量就越低,访问某块代码的地方越少,更改这块代码后所需要做的改动也就越少。

我们应该仅仅暴露哪些需要暴露的功能,对于其他类型,我们可以使用不同的方式,降低它们的可见性,例如将类型设置为internal或者private,注意可见性为private的类型也是可以实现接口的,我们还可以将这些类设置为内部类。

来看下面的代码变化过程,首先是第一版。

1 public class PhoneValidator
2 {
3 public bool ValidateNumber( PhoneNumber ph )
4 {
5 // perform validation.
6 // Check for valid area code, exchange.
7   return true;
8 }
9 }

上述代码提供了验证电话号码的功能,用户在使用时,直接实例化PhoneValidator对象,然后调用对象的ValidateNumber方法进行验证,这里的PhoneValidator类型是public的。

随着时间的推进,我们的验证方式可能会变得比较丰富,这时,就会产生第二版代码。

代码

1 public interface IPhoneValidator
2 {
3 bool ValidateNumber( PhoneNumber ph );
4 }
5
6
7 internal class USPhoneValidator : IPhoneValidator
8 {
9 public bool ValidateNumber( PhoneNumber ph )
10 {
11 // perform validation.
12 // Check for valid area code, exchange.
13 return true;
14 }
15 }
16
17
18 internal class InternationalPhoneValidator : IPhoneValidator
19 {
20 public bool ValidateNumber( PhoneNumber ph )
21 {
22 // perform validation.
23 // Check international code.
24 // Check specific phone number rules.
25 return true;
26 }
27 }
28

上述代码中定义了一个名为IPhoneValidator的接口,接口的类型是public,然后定义了两个实现了这个接口的类型,分别是USPhoneValidator和InternationalPhoneValidator,这两个类型都是internal的。这时用户在使用时,需要声明一个IPhoneValidator类型的实例,然后调用实例的ValidateNumber方法。注意:这里用户不能够直接实例对象了,这个过程需要放置在IPhoneValidator类型所在的程序集中,可以使用工厂模式进行实例化。

上面的示例中,体现的软件设计原则:1)面向接口编程,可以使得程序更加灵活;2)命令模式或者模板模式,如果是直接实现接口,那么就是命令模式,如果是采用集成抽象基类的方式,将共通的逻辑放置在基类中,那就是模板模式了。

我们通过公有方式暴露给外界的类和接口应该成为我们的合同:我们必须一致使用下去,程序对外接口越混乱,我们未来的方向就越受限制,我们向外暴露的公有类型越少,将来扩展和更改实现所拥有的选择就越多。

转载于:https://www.cnblogs.com/wing011203/archive/2010/01/23/1654764.html

Effective C# Item33:限制类型的可见性相关推荐

  1. Solidity的函数类型以及可见性分析(类比Java)

    函数类型 函数也是一种类型(值类型),它是函数的调用方式.函数类型可以被赋值吗,作为参数和返回结果.函数可以分为两类:内部函数(Internal)和外部函数(External). 内部函数Intern ...

  2. Effective Java之基本类型优于装箱类型(四十九)

    基本类型和装箱类型的区别: 1.基本类型只有值,而装箱类型是引用,有值和地址. 2.基本类型默认值不同,见下面程序. 3.基本类型比装箱类型更节省时间和空间. public class test {p ...

  3. 【《Effective C#》提炼总结】提高Unity中C#代码质量的21条准则

    原则1   尽可能地使用属性而不是可直接访问的数据成员         ● 属性(property)一直是C#语言中比较有特点的存在.属性允许将数据成员作为共有接口的一部分暴露出去,同时仍旧提供面向对 ...

  4. [.NET] 《Effective C#》快速笔记(三)- 使用 C# 表达设计

    <Effective C#>快速笔记(三)- 使用 C# 表达设计 目录 二十一.限制类型的可见性 二十二.通过定义并实现接口替代继承 二十三.理解接口方法和虚方法的区别 二十四.用委托实 ...

  5. 《Effective C#》快速笔记(三)- 使用 C# 表达设计

    目录 二十一.限制类型的可见性 二十二.通过定义并实现接口替代继承 二十三.理解接口方法和虚方法的区别 二十四.用委托实现回调 二十五.用事件模式实现通知 二十六.避免返回对内部类对象的引用 二十七. ...

  6. 《Effective C#中文版:改善C#程序的50种方法》读书笔记

    一.用属性代替可访问的字段 1..NET数据绑定只支持数据绑定,使用属性可以获得数据绑定的好处: 2.在属性的get和set访问器重可使用lock添加多线程的支持. 二.readonly(运行时常量) ...

  7. 类型的设计--类型和成员基础(一)

    6.1类型和成员基础 6.2类型的可见性 6.3成员的可见性 CLR术语 C#术语 描述 Private private 成员只有定义该成员的类型中的方法或该类型的所有嵌套类型中的方法访问 Famil ...

  8. 《CLR via C#》读书笔记 之 类型和成员基础

    第六章 类型和成员基础 2013-02-27 6.2 类型的可见性 6.3 成员的可访问性 6.6 组件.多态和版本控制 6.2 类型的可见性 返回 类有两种可见性: (1)       public ...

  9. 类型的设计--类型和成员基础(二)

    6.6组件.多态和版本控制 C#关键字 类型 方法/属性/事件 常量/字段 abstract 表示该类型不能构建实例 表示在构建派生类型的实例之前派生类型必须重写并实现这个成员 (不允许) virtu ...

最新文章

  1. C++:多线程中的小白(2)线程启动、结束、创建线程、join、detach
  2. win7压缩包安装mysql_win7怎么安装mysql5.7.13压缩文件图解
  3. 网页3D效果库Three.js学习[二]-了解照相机
  4. python教程:利用while求100内的整数和
  5. python 多版本管理
  6. SpringBoot与SpringCloud的关系与区别
  7. link rel=canonical 用法
  8. PIL修改带有透明像素的png图片颜色
  9. ADSL与路由器密码大全及设置
  10. 利用VB2005制作颜色渐变的进度条
  11. 文档交接说明书(模板)
  12. 用vba实现一个简单的工资系统
  13. ICTCLAS 汉语词性标注集 中科院
  14. 超级计算机排名太湖之光,神威•太湖之光继续“称霸”超级计算机排行榜 美国无缘前三...
  15. c语言用随机投点法计算圆周率,(原创精品)用随机投点法计算π值【compute π with dartpoint randomly】...
  16. WiFi信号图标等级计算
  17. python怎么隐藏输入法_如何创建隐藏的文本输入框?
  18. 基于node建立聊天室浅谈
  19. 服务器创建虚拟主机,服务器创建虚拟主机
  20. can分析仪、usb接口can卡的的型号定义

热门文章

  1. 如何用木板做桥_为这份动手能力点赞!旧木板打磨后做成橱柜,效果可媲美定制的...
  2. python坐标图设计_python 三维坐标图
  3. python中的switch语句_python技巧 switch case语句
  4. 数据库封装 sql server mysql_mysql操作数据库进行封装实现增删改查功能
  5. Zookeeper集群详解
  6. mybatis批量更新及其效率问题
  7. 作为开发,你对进程和线程能否区分开来呢?
  8. IDEA maven依赖下载失败
  9. PostgreSQL 12系统表(5)pg_index
  10. 图像检索从入门到进阶