A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

(二)设计模式的六大原则
4.依赖倒置原则
5.接口隔离原则
6.开闭原则
4.依赖倒置原则
依赖倒置原则:高层模块不应该依赖于低层模块,应该通过抽象依赖,而不是依赖低层,这里的抽象指的是抽象类/接口,细节指的就是一切都明确的普通类,
以下面例子来说明:
首先先创建一个抽象类AbstractCar,抽闲类里添加一个Drive抽象方法
[Java] 纯文本查看 复制代码
 public abstract class AbstractCar
 {
     public abstract void Drive();
 }

然后在分别创建都继承抽象类(AbstractCar)的BenzCar 类和BmwCar ,并且实现AbstractCar里的抽象方法Drive
[Java] 纯文本查看 复制代码
 	public class BenzCar : AbstractCar
    {
        public override void Drive()
        {
            Console.WriteLine($"Drive:{this.GetType().Name}");

        }
    }


    public class BmwCar : AbstractCar
    {
        public override void Drive()
        {
            Console.WriteLine($"Drive:{this.GetType().Name}");
        }
    }

在然后我们添加一个Person类,里面包含了属性,方法。。。
[Java] 纯文本查看 复制代码
	public class Person
    {
        public int ID { get; set; }

        public string Name { get; set; }

        public void CanBenzCar(BenzCar cars)
        {
            cars.Drive();
        }

        public void CanBmwCar(BmwCar cars)
        {
            cars.Drive();
        }
    }

最后
[Java] 纯文本查看 复制代码
 		static void Main(string[] args)
        {
            Person p = new Person()
            {
                ID=1,
                Name="被煮了的小螃蟹"
            };

            BmwCar bmwCar = new BmwCar();
            p.CanBmwCar(bmwCar);

            BenzCar benzCar = new BenzCar();
            p.CanBenzCar(benzCar);
        }

根据上面代码我们看出,这种写法,如果在添加一个PorscheCar类,我还要在修改Person类,,如果添加更多的类,我就要在Person类中添加更多的相应方法,这种就是依赖低层,这样的代码量多了就容易出现问题。所以这时我们就采取一种方法----------------面向抽象---------直接在Person类中添加方法CanCar,抽象类AbstractCar作为参数传进来,这样只要是AbstractCar 类和继承AbstractCar的类都可以使用。
[Java] 纯文本查看 复制代码
 	public class Person
    {
        public int ID { get; set; }

        public string Name { get; set; }

        public void CanCar(AbstractCar cars)
        {
            cars.Drive();
        }
    }

当然这里也可以使用泛型,不过使用泛型和抽象两者性能方面会不一样
[Java] 纯文本查看 复制代码
public void CanCarT<T>(T cars) where T : AbstractCar
{
     cars.Drive();
}

5.接口隔离原则
接口隔离原则:一个类对另一个类 的依赖应该建立在最小的接口,而不应该依赖它不需要的接口。
下面这的代码,一个手机的抽象类,一个Vivo和oppo的实现类。这里的抽象有个问题,就是Call(打电话)和Send(发短信)是手机的通用功能,但是它的Video(录音),Pay(支付),Map(地图),Photo(拍照)有的手机是没有这样的功能的,比如老年机,这样显而易见是不可以行,所以我们这个是有就用到了接口Interface来进行补充。
[Java] 纯文本查看 复制代码
    public abstract class AbstractPhone
    {
        public abstract void Call();
        public abstract void Send();

        public abstract void Video();
        public abstract void Pay();
        public abstract void Map();
        public abstract void Photo();
    }

    public class VivoPhone : AbstractPhone
    {
        public override void Call()
        {
            Console.WriteLine("Vivo:Call");
        }

        public override void Map()
        {
            Console.WriteLine("Vivo:Map");
        }

        public override void Pay()
        {
            Console.WriteLine("Vivo:Pay");
        }

        public override void Photo()
        {
            Console.WriteLine("Vivo:Photo");
        }

        public override void Send()
        {
            Console.WriteLine("Vivo:Send");
        }

        public override void Video()
        {
            Console.WriteLine("Vivo:Video");
        }
    }


    public class OppoPhone : AbstractPhone
    {
        public override void Call()
        {
            Console.WriteLine("Oppo:Call");
        }

        public override void Map()
        {
            Console.WriteLine("Oppo:Map");
        }

        public override void Pay()
        {
            Console.WriteLine("Oppo:Pay");
        }

        public override void Photo()
        {
            Console.WriteLine("Oppo:Photo");
        }

        public override void Send()
        {
            Console.WriteLine("Oppo:Send");
        }

        public override void Video()
        {
            Console.WriteLine("Oppo:Video");
        }
    }

那我们改成接口补充的话:如下
[Java] 纯文本查看 复制代码
   public abstract class AbstractPhone 
    {
        public abstract void Call();
        public abstract void Send();
    }

    public interface IPhone
    {
        void Video();
        void Pay();
        void May();
        void Photo();
    }
    public class VivoPhone : AbstractPhone, IPhone
    {
        public override void Call()
        {
            Console.WriteLine("Vivo:Call");
        }
		public override void Send()
        {
            throw new NotImplementedException();
        }
        public void May()
        {
            Console.WriteLine("Vivo:May");
        }
        public void Pay()
        {
            Console.WriteLine("Vivo:Pay");
        
        public void Photo()
        {
            Console.WriteLine("Vivo:Photo");
        }
        public void Video()
        {
            Console.WriteLine("Vivo:Video");
        }
    }
    
    public class OppoPhone : AbstractPhone, IPhone
    {
        public override void Call()
        {
            Console.WriteLine("Oppo:Call");
        }

        public void May()
        {
            Console.WriteLine("Oppo:May");
        }

        public void Pay()
        {
            Console.WriteLine("Oppo:Pay");
        }

        public void Photo()
        {
            Console.WriteLine("Oppo:Photo");
        }

        public override void Send()
        {
            Console.WriteLine("Oppo:Send");
        }

        public void Video()
        {
            Console.WriteLine("Oppo:Video");
        }
    }

但是这样写的话还是有一问题,我们要知道的是接口是不局限于产品的,这里使用的是手机,如果传一个其他的(电视,电脑,游戏机,车载导航)也都可以,但是这样有的产品就不会都满足接口里的方法,比如游戏机是不能拍照的,所以这时还要继续将接口进行拆分,来满足依赖应该建立在最小的接口的原则。
这里要注意的是:也不能一个方法一个接口,这样抽象就没有任何意义了。那至于如何拆分接口?还是要看项目功能。而且也是会随着业务发展会有所变化,不过这要在设计的时候提前留好。

6.开闭原则
开闭原则:开放扩展代码(类),关闭修改代码(类)
面向对象语言是是一个静态语言,它最怕的就是不断修改,测试好的再去修改会波及很多东西,所以我们希望的是对原有的代码没有改动,就是新增类。
开闭原则只是一个目标,它没有任何是实现手段,他可以成为六大原则的总则。
其他的5大原则的建议其实就是为了能后更好的实现开闭原则,这也是面向对象语言开发的一个终极目标
转自:https://blog.csdn.net/qq_30022691/article/details/105629164

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马