(二)设计模式的六大原则
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
|