1. 只与你的朋友说话 2. 不和陌生人说话 3. 对象应该只与必须交互的对象通信
通俗地讲,一个类应该对自己需要调用的类知道得最少,你调用的类的内部是如何实现的,都和我没关系,那是你的事情,我就知道你提供的接口方法,我就调用这么多,其他的一概不关心。
(1) 当前对象本身(this); (2) 以参数形式传入到当前对象方法中的对象; (3) 当前对象的成员对象; (4) 如果当前对象的成员对象是一个集合,那么集合中的元素也都是可以交互的; (5) 当前对象所创建的对象。
此外,还需要适当设置对象的访问权限。
// 方法链式调用,此种方式在Web页面开发中倒是常用,但是静态语言中似乎不推荐 public void Do() { m_accessor.GetUser().Rename(); } // 无谓的公开方法 class UI { public void Do() { WorkHelper(); } public void WorkHelper() { } }
public class Program { static void Main(string[] args) { User user = new User(); View ui = new View(user); user.Name = "Hello"; } } delegate void OnNameChange(string name); class View { public View(User user) { user.onNameChanged += user_onNameChanged; } void user_onNameChanged(string name) { Console.WriteLine(name); } } class User { private string m_name; public string Name { get { return m_name; } set { m_name = value; onNameChanged(m_name); } } public event OnNameChange onNameChanged; }
这也是简单的MVC模式中的MV之间的交互方式,View作为事件的接收者,只需要提供好回调函数,当Model部分发生变化时,View自动接收到变化去更新UI(此处只是打印了出来)。
class User { public virtual void PrintType() { } } class Admin : User { public override void PrintType() { Console.WriteLine("Employer"); } } class Programmer : User { public override void PrintType() { Console.WriteLine("Employer"); } } class Manager : User { public override void PrintType() { Console.WriteLine("Employer"); } } class Contractor : User { public override void PrintType() { Console.WriteLine("Temp"); } }
公司的系统中除了Contractor外几乎全是正式员工,打印类型的时候只需要打印Employer即可,而只有Contractor需要打印Temp。
public class Program { static void Main(string[] args) { User admin = new Admin(new EmployerPrintor()); admin.PrintType(); User contractor = new Contractor(new TempPrintor()); contractor.PrintType(); } } class User { Printor m_printor; public User(Printor printor) { m_printor = printor; } public virtual void PrintType() { m_printor.PrintType(); } } class Admin : User { public Admin(Printor printor) :base(printor) { } } class Contractor : User { public Contractor(Printor printor) : base(printor) { } } class Printor { public virtual void PrintType() { } } class EmployerPrintor : Printor { public override void PrintType() { Console.WriteLine("Employer"); } } class TempPrintor : Printor { public override void PrintType() { Console.WriteLine("Temp"); } }
对于这个原则,其实我自己宁愿描述为:合理使用继承与组合。作为复用和描述对象关系的两种最基本的手段,我想说的是适合继承的使用场景时候还是得用继承,适合使用组合的时候就使用组合。