依賴倒置原則(二)
依賴倒置原則就是抽象類和接口在使用時的一些規範和建議,我們的應用上層模塊不直接依賴於下層模塊,不具體依賴某個類或者對象,而是依賴於某個抽象。
接著上一節的Demo,我們有3個手機的對象。分別是LumiaPhone,Galaxy,ApplePhone,現在我們新增一個Student學生類,學生會使用手機。有可能使用LumiaPhone手機,也有可能使用Galaxy,也有可能使用
ApplePhone,那我們的Student看起來的得實現成這樣:
public class Student { public int Id { get; set; } public string Name { get; set; } public void PlayPhone(LumiaPhone lumiaPhone) { Console.WriteLine($"{Name} use {lumiaPhone.Name}"); } public void PlayApplePhone(ApplePhone applePhone) { Console.WriteLine($"{Name} use {applePhone.Name}"); } public void PlayGalaxy(Galaxy galaxy) { Console.WriteLine($"{Name} use {galaxy.Name}"); } }
具體使用時,我們可能會是這樣: 先創建一個Student再根據學生使用的某種手機 調用不同的play方法
LumiaPhone lumiaPhone = new LumiaPhone(); ApplePhone applePhone = new ApplePhone(); Galaxy galaxy = new Galaxy(); Student student = new Student(); student.PlayPhone(lumiaPhone); student.PlayApplePhone(applePhone); student.PlayGalaxy(galaxy);
這個時候假設Student舊的手機壞了,換了新的華為手機,那我們新增一個Honor對象
public class Honor { public void System() { Console.WriteLine("Hua Wei Honor"); } }
再修改Student類 新增一個方法
public void PlayHonor(Honor honor) { Console.WriteLine($"{Name} use {honor.Name}"); }
使用時
Honor honor = new Honor(); student.PlayHonor(honor);
手機有太多種類,每次新增對象我們都要在Student中新增方法 在調用處進行手機的實例化,維護起來 非常麻煩,容易出錯。不利於擴展,所以我們的Student 不應該依賴於具體的類,而是應該依賴抽象 上一遍提到的BasePhone,我們來改造下代碼 Student會變成這樣
public class Student { public int Id { get; set; } public string Name { get; set; } public void PlayPhone(BasePhone basePhone) { Console.WriteLine($"{Name} use {basePhone.Name}"); } //public void PlayPhone(LumiaPhone lumiaPhone) //{ // Console.WriteLine($"{Name} use {lumiaPhone.Name}"); //} //public void PlayApplePhone(ApplePhone applePhone) //{ // Console.WriteLine($"{Name} use {applePhone.Name}"); //} //public void PlayGalaxy(Galaxy galaxy) //{ // Console.WriteLine($"{Name} use {galaxy.Name}"); //} //public void PlayHonor(Honor honor) //{ // Console.WriteLine($"{Name} use {honor.Name}"); //} }
我們的調用處
static void Main(string[] args)
{
{
LumiaPhone lumiaPhone = new LumiaPhone();
ApplePhone applePhone = new ApplePhone();
Galaxy galaxy = new Galaxy();
Honor honor = new Honor();
Student student = new Student();
student.PlayPhone(lumiaPhone);
student.PlayPhone(applePhone);
student.PlayPhone(galaxy);
student.PlayPhone(honor);
//student.PlayPhone(lumiaPhone);
//student.PlayApplePhone(applePhone);
//student.PlayGalaxy(galaxy);
//student.PlayHonor(honor);
}
Console.ReadKey();
}
這個時候感覺Main還是依賴了具體的對象Student,以學生使用honor手機為例
BasePhone honor = new Honor(); Student student = new Student(); student.PlayPhone(honor);
我們新增一個SimpleFactory及接口IPlayPhone
public static class SimpleFactory { public static BasePhone CreatePhone() { return new Honor(); } public static Student CreateStudent() { return new Student(); } }
public interface IPlayPhone { void PlayPhone(BasePhone basePhone); }
那我們的Main方法則變成
static void Main(string[] args) { { BasePhone honor = SimpleFactory.CreatePhone(); IPlayPhone student = SimpleFactory.CreateStudent(); student.PlayPhone(honor); //Honor honor = new Honor(); //Student student = new Student(); //student.PlayPhone(honor); //student.PlayPhone(lumiaPhone); //student.PlayApplePhone(applePhone); //student.PlayGalaxy(galaxy); //student.PlayHonor(honor); } Console.ReadKey(); }
我在這個demo SimpleFactory裏直接返回了一個對象,項目中是可以通過讀取配置文件反射來構造實的
這樣只要通過改配置文件 就可以實現學生更換手機的功能,同樣通過配置文件 也可以實現 老師使用手機只要我們新增一個Teacher類 實現IPlayPhone接口。其他代碼不需要任何改動, 這就是我們原則 依賴抽象或接口 而不應該依賴於具體的細節的好處, 這裏學生,老師其實就是上層,而我們的手機則是下層,上層不應該依賴下層 而是應該依賴抽象
本文出自 “myself” 博客,請務必保留此出處http://ccandzy.blog.51cto.com/13163569/1967181
依賴倒置原則(二)