依赖注入之接口注入

来源:互联网 发布:unity3d创建x相机 编辑:程序博客网 时间:2024/05/16 14:43

面向接口编程,而不要面向实现编程  


Program to an interface, not an implementation.面向接口编程,而不要面向实现编程。)

嘿!对于这个原则,不论是耳朵还是眼睛,是不是都太熟悉了!“接口”这个词已经被赋予太多的含义,搞的大家一说点儿屁事就满嘴往外蹦“接口”。那么它到底是什么意思呢?我们这里说的接口是一个抽象的概念,不局限于语言层面的接口(例如C#里的interface)。一个接口也可以是一个抽象类,或者一个基类也可以看作是一种接口的表现形式,因为基类变量可以用来引用其子类。要点在于,我们在面向接口编程的时候,可以使用多态,那么实际运行的代码只依赖于具体的接口(interface,抽象类,基类),而不管这些接口提供的功能是如何实现的,也就是说,接口将系统的不同部分隔离开来,同时又将它们连接在一起。我的神啊!接口真是太伟大了!

OK!这回该彻底解决Joe的问题了!

根据面向接口编程的设计原则,我们应该用接口来隔离鸭子问题中变化的部分,也就是鸭子的不稳定的行为(fly()quack())。我们要用一个FlyBehavior接口表示鸭子的飞行行为,这个接口可以有多种不同的实现方式,可以“横”着分,也可以“竖”着分,管它呢!这样做的好处就是我们将鸭子的行为实现在一组独立的类里,具体的鸭子是通过FlyBehavior这个接口来调用这个行为的,因为Duck只依赖FlyBehavior接口,所以不需要管FlyBehavior是如何被实现的。如下面的类图,FlyBehaviorQuackBehavior接口都有不同的实现方式!

Joe已经晕了,“你说了这么多,全是大白话,来点代码行不行,我要C#的!”。说到这里,我们也该开始彻底改造这个设计了,并会在最后附加部分代码来帮助大家理解。  

第一步:我们要给Duck类增加两个接口类型的实例变量,分别是flyBehaviorquackBehavior,它们其实就是新的设计里的“飞行”和“叫唤”行为。每个鸭子对象都将会使用各种方式来设置这些变量,以引用它们期望的运行时的特殊行为类型(使用横着飞,吱吱叫,等等)

跟踪fly代码:

前台调用 program.cs

    class Program
    {
        public static void Main(string[] args)
        {
            MallardDuck mallardDuck = new MallardDuck();
            RedheadDuck redheadDuck = new RedheadDuck();
            RubberDuck rubberDuck = new RubberDuck();

            Console.WriteLine(mallardDuck.Display() + " # " + mallardDuck.PerformFly().ToString() + " # " + mallardDuck.PerformQuack().ToString());
            Console.WriteLine(redheadDuck.Display() + " # " + redheadDuck.PerformFly().ToString() + " # " + redheadDuck.PerformQuack().ToString());
            Console.WriteLine(rubberDuck.Display() + " # " + rubberDuck.PerformFly().ToString() + " # " + rubberDuck.PerformQuack().ToString());
            
            Console.ReadLine();
        }
    }

父类:Duck:

    public abstract class Duck
    {
        protected IFlyBehavior flyBehavior; // 定义一个接口变量(其实也是一个类)
        protected IQuackBehavior quackBehavior;

        public string Swim()
        {
            return "所有的鸭子都可以游泳!";
        }

        public object PerformFly()
        {
            return flyBehavior.Fly();  //返回类的Fly()方法
        }

        public object PerformQuack()
        {
            return quackBehavior.Quack();
        }


        public void SetQuackBehavior(IQuackBehavior qck)
        {
            this.quackBehavior = qck;
        }

    public void SetFlyBehavoir(IFlyBehavior fly)   //方法是fly
        {
            this.flyBehavior = fly;
        }

        public abstract object Display();     
    }

 

子类:MallardDuck.cs

 public class MallardDuck : Duck
 {
  public MallardDuck()
  {
            base.SetQuackBehavior(new Quack1()); 

        base.SetFlyBehavoir(new FlyWithWings());

//继承父类:接口作为参数

//采用设定方法,而不是在构造器内自己创建方法,方法是委托给FlyWithWings()

  }

  public override object Display()
  {
   return "我是一只野鸭!";
   
  }
 }

接口

 public interface IFlyBehavior
 {
  object Fly();
 }

方法实现类(委托接受者)FlyWithWings

 public class FlyWithWings : IFlyBehavior
 {
  public FlyWithWings()
  {}

  #region IFlyBehavior Members

  public object Fly()
  {
   return "我飞啦!";
  }

  #endregion
 }

原创粉丝点击