<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          C#軟件架構(gòu)設(shè)計(jì)原則

          共 19080字,需瀏覽 39分鐘

           ·

          2023-11-11 23:44

          軟件架構(gòu)設(shè)計(jì)原則


          學(xué)習(xí)設(shè)計(jì)原則是學(xué)習(xí)設(shè)計(jì)模式的基礎(chǔ)。在實(shí)際的開(kāi)發(fā)過(guò)程中,并不是一定要求所有的代碼都遵循設(shè)計(jì)原則,而是要綜合考慮人力、成本、時(shí)間、質(zhì)量,不刻意追求完美,要在適當(dāng)?shù)膱?chǎng)景遵循設(shè)計(jì)原則。

          這體現(xiàn)的是一種平衡取舍,可以幫助我們?cè)O(shè)計(jì)出更加優(yōu)雅的代碼結(jié)構(gòu)。

          分別用一句話歸納總結(jié)軟件設(shè)計(jì)七大原則,如下表所示。

          設(shè)計(jì)原則 一句話歸納 目的
          開(kāi)閉原則 對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉 降低對(duì)維護(hù)帶來(lái)的新風(fēng)險(xiǎn)
          依賴(lài)倒置原則 高層不應(yīng)該依賴(lài)底層 更利于代碼結(jié)構(gòu)的升級(jí)擴(kuò)展
          單一職責(zé)原則 一個(gè)類(lèi)只干一件事 便于理解,提高代碼的可讀性
          接口隔離原則 一個(gè)接口只干一件事 功能解耦,高聚合、低耦合
          迪米特法則 不該知道的不要知道 只和朋友交流,不和陌生人說(shuō)話,減少代碼臃腫
          里氏替換原則 子類(lèi)重寫(xiě)方式功能發(fā)生改變,不應(yīng)該影響父類(lèi)方法的含義 防止繼承泛濫
          合成復(fù)用原則 盡量使用組合實(shí)現(xiàn)代碼復(fù)用,而不使用繼承 降低代碼耦合
          開(kāi)閉原則示例

          當(dāng)使用C#編程語(yǔ)言時(shí),可以通過(guò)以下示例來(lái)說(shuō)明開(kāi)閉原則的應(yīng)用:

          假設(shè)我們正在設(shè)計(jì)一個(gè)圖形繪制應(yīng)用程序,其中包含不同類(lèi)型的圖形(如圓形、矩形、三角形等)。

          我們希望能夠根據(jù)需要輕松地添加新的圖形類(lèi)型,同時(shí)保持現(xiàn)有代碼的穩(wěn)定性。

          首先,我們定義一個(gè)抽象基類(lèi) Shape 來(lái)表示所有圖形的通用屬性和行為:

          public abstract class Shape
          {
              public abstract void Draw();
          }

          然后,我們創(chuàng)建具體的圖形類(lèi),如 Circle、RectangleTriangle,它們都繼承自 Shape 基類(lèi),并實(shí)現(xiàn)了 Draw() 方法:

          public class Circle : Shape
          {
              public override void Draw()
              {
                  Console.WriteLine("Drawing a circle");
              }
          }

          public class Rectangle : Shape
          {
              public override void Draw()
              {
                  Console.WriteLine("Drawing a rectangle");
              }
          }

          public class Triangle : Shape
          {
              public override void Draw()
              {
                  Console.WriteLine("Drawing a triangle");
              }
          }

          現(xiàn)在,如果我們需要添加新的圖形類(lèi)型(例如橢圓),只需創(chuàng)建一個(gè)新的類(lèi)并繼承自 Shape 類(lèi)即可。這樣做不會(huì)影響現(xiàn)有代碼,并且可以輕松地?cái)U(kuò)展應(yīng)用程序。

          public class Ellipse : Shape
          {
              public override void Draw()
              {
                  Console.WriteLine("Drawing an ellipse");
              }
          }

          在應(yīng)用程序的其他部分,我們可以使用 Shape 類(lèi)型的對(duì)象來(lái)繪制不同的圖形,而無(wú)需關(guān)心具體的圖形類(lèi)型。這樣,我們遵循了開(kāi)閉原則,對(duì)擴(kuò)展開(kāi)放(通過(guò)添加新的圖形類(lèi)型),對(duì)修改關(guān)閉(不需要修改現(xiàn)有代碼)。

          public class DrawingProgram
          {
              public void DrawShapes(List<Shape> shapes)
              {
                  foreach (var shape in shapes)
                  {
                      shape.Draw();
                  }
              }
          }

          使用示例:

          var shapes = new List<Shape>
          {
              new Circle(),
              new Rectangle(),
              new Triangle(),
              new Ellipse()
          };

          var drawingProgram = new DrawingProgram();
          drawingProgram.DrawShapes(shapes);

          輸出結(jié)果:

          Drawing a circle
          Drawing a rectangle
          Drawing a triangle
          Drawing an ellipse

          通過(guò)遵循開(kāi)閉原則,我們可以輕松地?cái)U(kuò)展應(yīng)用程序并添加新的圖形類(lèi)型,而無(wú)需修改現(xiàn)有代碼。這樣可以提高代碼的可維護(hù)性和可擴(kuò)展性,并支持軟件系統(tǒng)的演化和變化。

          單一職責(zé)示例

          單一職責(zé)原則(Single Responsibility Principle,SRP)要求一個(gè)類(lèi)應(yīng)該只有一個(gè)引起它變化的原因。換句話說(shuō),一個(gè)類(lèi)應(yīng)該只負(fù)責(zé)一項(xiàng)職責(zé)或功能。

          下面是一個(gè)使用C#示例來(lái)說(shuō)明單一職責(zé)原則的應(yīng)用:

          假設(shè)我們正在開(kāi)發(fā)一個(gè)學(xué)生管理系統(tǒng),其中包含學(xué)生信息的錄入和展示功能。我們可以將這個(gè)系統(tǒng)分為兩個(gè)類(lèi):StudentStudentManager。

          首先,定義 Student 類(lèi)來(lái)表示學(xué)生對(duì)象,并包含與學(xué)生相關(guān)的屬性和方法:

          public class Student
          {
              public string Name { getset; }
              public int Age { getset; }

              // 其他與學(xué)生相關(guān)的屬性和方法...
          }

          然后,創(chuàng)建 StudentManager 類(lèi)來(lái)處理與學(xué)生信息管理相關(guān)的操作,如錄入、查詢和展示等:

          public class StudentManager
          {
              private List<Student> students;

              public StudentManager()
              {
                  students = new List<Student>();
              }

              public void AddStudent(Student student)
              {
                  // 將學(xué)生信息添加到列表中...
                  students.Add(student);
                  Console.WriteLine("Student added successfully.");
              }

              public void DisplayStudents()
              {
                  // 展示所有學(xué)生信息...
                  foreach (var student in students)
                  {
                      Console.WriteLine($"Name: {student.Name}, Age: {student.Age}");
                  }
             }
          }

          在這個(gè)例子中,Student 類(lèi)負(fù)責(zé)表示單個(gè)學(xué)生對(duì)象,并封裝了與學(xué)生相關(guān)的屬性。而 StudentManager 類(lèi)負(fù)責(zé)處理學(xué)生信息的管理操作,如添加學(xué)生和展示學(xué)生信息。

          使用示例:

          var student1 = new Student { Name = "Alice", Age = 20 };
          var student2 = new Student { Name = "Bob", Age = 22 };

          var studentManager = new StudentManager();
          studentManager.AddStudent(student1);
          studentManager.AddStudent(student2);

          studentManager.DisplayStudents();

          輸出結(jié)果:

          Student added successfully.
          Student added successfully.
          Name: Alice, Age: 20
          Name: Bob, Age: 22

          通過(guò)將學(xué)生對(duì)象的表示和管理操作分別封裝在不同的類(lèi)中,我們遵循了單一職責(zé)原則。Student 類(lèi)只負(fù)責(zé)表示學(xué)生對(duì)象的屬性,而 StudentManager 類(lèi)只負(fù)責(zé)處理與學(xué)生信息管理相關(guān)的操作。這樣可以提高代碼的可維護(hù)性和可擴(kuò)展性,并使每個(gè)類(lèi)都具有清晰明確的職責(zé)。

          里式替換

          里氏替換原則(Liskov Substitution Principle,LSP)要求子類(lèi)型必須能夠替換其基類(lèi)型,并且不會(huì)破壞程序的正確性。也就是說(shuō),子類(lèi)可以在不影響程序正確性和預(yù)期行為的情況下替代父類(lèi)。

          下面是一個(gè)使用C#示例來(lái)說(shuō)明里式替換原則的應(yīng)用:

          假設(shè)我們正在開(kāi)發(fā)一個(gè)圖形繪制應(yīng)用程序,其中包含多種形狀(如圓形、矩形等)。我們希望能夠根據(jù)用戶選擇的形狀類(lèi)型進(jìn)行繪制操作。

          首先,定義一個(gè)抽象基類(lèi) Shape 來(lái)表示所有形狀對(duì)象,并聲明一個(gè)抽象方法 Draw 用于繪制該形狀:

          public abstract class Shape
          {
              public abstract void Draw();
          }

          然后,創(chuàng)建具體的子類(lèi)來(lái)表示不同的形狀。例如,創(chuàng)建 Circle 類(lèi)和 Rectangle 類(lèi)分別表示圓形和矩形,并實(shí)現(xiàn)它們自己特定的繪制邏輯:

          public class Circle : Shape
          {
              public override void Draw()
              {
                  Console.WriteLine("Drawing a circle...");
              }
          }

          public class Rectangle : Shape
          {
              public override void Draw()
              {
                  Console.WriteLine("Drawing a rectangle...");
              }
          }

          在這個(gè)例子中,每個(gè)具體的子類(lèi)都可以替代其基類(lèi) Shape 并實(shí)現(xiàn)自己特定的繪制邏輯。這符合里式替換原則,因?yàn)闊o(wú)論是 Circle 還是 Rectangle 都可以在不破壞程序正確性和預(yù)期行為的情況下替代 Shape

          使用示例:

          Shape circle = new Circle();
          circle.Draw();  // 輸出 "Drawing a circle..."

          Shape rectangle = new Rectangle();
          rectangle.Draw();  // 輸出 "Drawing a rectangle..."

          通過(guò)將具體的子類(lèi)對(duì)象賦值給基類(lèi)引用變量,并調(diào)用相同的方法,我們可以看到不同形狀的繪制操作被正確地執(zhí)行。這證明了里式替換原則的有效性。

          總結(jié):里式替換原則要求子類(lèi)型必須能夠替代其基類(lèi)型,并且不會(huì)破壞程序正確性。在C#中,我們可以通過(guò)創(chuàng)建具體的子類(lèi)來(lái)表示不同形狀,并確保它們能夠在繼承自抽象基類(lèi)時(shí)正確地實(shí)現(xiàn)自己特定的行為。這樣可以提高代碼的可擴(kuò)展性和靈活性,并使得代碼更易于維護(hù)和重用。

          依賴(lài)倒置

          依賴(lài)倒置原則(Dependency Inversion Principle,DIP)要求高層模塊不應(yīng)該依賴(lài)于低層模塊的具體實(shí)現(xiàn),而是應(yīng)該依賴(lài)于抽象。同時(shí),抽象不應(yīng)該依賴(lài)于具體實(shí)現(xiàn)細(xì)節(jié),而是應(yīng)該由高層模塊定義。

          下面是一個(gè)使用C#示例來(lái)說(shuō)明依賴(lài)倒置原則的應(yīng)用:

          假設(shè)我們正在開(kāi)發(fā)一個(gè)電子商務(wù)系統(tǒng),其中包含訂單處理和支付功能。我們希望能夠根據(jù)用戶選擇的支付方式進(jìn)行訂單支付操作。

          首先,定義一個(gè)抽象接口 IPaymentProcessor 來(lái)表示支付處理器,并聲明一個(gè)方法 ProcessPayment 用于執(zhí)行訂單支付:

          public interface IPaymentProcessor
          {
              void ProcessPayment(decimal amount);
          }

          然后,在具體的實(shí)現(xiàn)類(lèi)中分別實(shí)現(xiàn)不同的支付方式。例如,創(chuàng)建 CreditCardPaymentProcessor 類(lèi)和 PayPalPaymentProcessor 類(lèi)分別表示信用卡和PayPal支付,并實(shí)現(xiàn)它們自己特定的支付邏輯:

          public class CreditCardPaymentProcessor : IPaymentProcessor
          {
              public void ProcessPayment(decimal amount)
              {
                  Console.WriteLine($"Processing credit card payment of {amount} dollars...");
                  // 具體信用卡支付邏輯...
              }
          }

          public class PayPalPaymentProcessor : IPaymentProcessor
          {
              public void ProcessPayment(decimal amount)
              {
                  Console.WriteLine($"Processing PayPal payment of {amount} dollars...");
                  // 具體PayPal支付邏輯...
              }
          }

          在這個(gè)例子中,每個(gè)具體的支付處理器都實(shí)現(xiàn)了 IPaymentProcessor 接口,并提供了自己特定的支付邏輯。這樣,高層模塊(訂單處理模塊)就可以依賴(lài)于抽象接口 IPaymentProcessor 而不是具體的實(shí)現(xiàn)類(lèi)。

          使用示例:

          public class OrderProcessor
          {
              private IPaymentProcessor paymentProcessor;

              public OrderProcessor(IPaymentProcessor paymentProcessor)
              {
                  this.paymentProcessor = paymentProcessor;
              }

              public void ProcessOrder(decimal amount)
              {
                  // 處理訂單邏輯...

                  // 使用依賴(lài)注入的方式調(diào)用支付處理器
                  paymentProcessor.ProcessPayment(amount);

                  // 其他訂單處理邏輯...
              }
          }

          // 在應(yīng)用程序中配置和使用不同的支付方式
          var creditCardPayment = new CreditCardPaymentProcessor();
          var payPalPayment = new PayPalPaymentProces 

          接口隔離

          接口隔離原則(Interface Segregation Principle,ISP)要求客戶端不應(yīng)該依賴(lài)于它們不使用的接口。一個(gè)類(lèi)應(yīng)該只依賴(lài)于它需要的接口,而不是依賴(lài)于多余的接口。

          下面是一個(gè)使用C#示例來(lái)說(shuō)明接口隔離原則的應(yīng)用:

          假設(shè)我們正在開(kāi)發(fā)一個(gè)文件管理系統(tǒng),其中包含文件上傳和文件下載功能。我們希望能夠根據(jù)用戶需求提供相應(yīng)的功能。

          首先,定義兩個(gè)接口 IFileUploadableIFileDownloadable 來(lái)表示文件上傳和文件下載功能,并分別聲明相應(yīng)的方法:

          public interface IFileUploadable
          {
              void UploadFile(string filePath);
          }

          public interface IFileDownloadable
          {
              void DownloadFile(string fileId);
          }

          然后,在具體的實(shí)現(xiàn)類(lèi)中分別實(shí)現(xiàn)這兩個(gè)功能。例如,創(chuàng)建 LocalFileManager 類(lèi)來(lái)處理本地文件操作,并實(shí)現(xiàn)對(duì)應(yīng)的方法:

          public class LocalFileManager : IFileUploadableIFileDownloadable
          {
              public void UploadFile(string filePath)
              {
                  Console.WriteLine($"Uploading file from local path: {filePath}");
                  // 具體本地上傳邏輯...
              }

              public void DownloadFile(string fileId)
              {
                  Console.WriteLine($"Downloading file with ID: {fileId} to local path");
                  // 具體本地下載邏輯...
              }
          }

          在這個(gè)例子中,每個(gè)具體的實(shí)現(xiàn)類(lèi)只關(guān)注自己需要用到的接口方法,而不需要實(shí)現(xiàn)多余的方法。這符合接口隔離原則,因?yàn)榭蛻舳丝梢愿鶕?jù)需要依賴(lài)于相應(yīng)的接口。

          使用示例:

          public class FileManagerClient
          {
              private IFileUploadable fileUploader;
              private IFileDownloadable fileDownloader;

              public FileManagerClient(IFileUploadable fileUploader, IFileDownloadable fileDownloader)
              {
                  this.fileUploader = fileUploader;
                  this.fileDownloader = fileDownloader;
              }

              public void UploadAndDownloadFiles(string filePath, string fileId)
              {
                  // 使用文件上傳功能
                  fileUploader.UploadFile(filePath);

                  // 使用文件下載功能
                  fileDownloader.DownloadFile(fileId);
                  
                  // 其他操作...
              }
          }

          // 在應(yīng)用程序中配置和使用具體的文件管理類(lèi)
          var localFileManager = new LocalFileManager();
          var client = new FileManagerClient(localFileManager, localFileManager);
          client.UploadAndDownloadFiles("path/to/file""123456");

          通過(guò)依賴(lài)注入的方式,我們可以將具體的實(shí)現(xiàn)類(lèi)傳遞給客戶端,并根據(jù)需要調(diào)用相應(yīng)的接口方法。這樣就遵循了接口隔離原則,使得客戶端只依賴(lài)于它們所需的接口,并且不會(huì)受到多余方法的影響。這提高了代碼的可維護(hù)性和靈活性,并促進(jìn)了代碼重用和擴(kuò)展。

          迪米特

          迪米特法則(Law of Demeter,LoD),也稱(chēng)為最少知識(shí)原則(Principle of Least Knowledge),要求一個(gè)對(duì)象應(yīng)該對(duì)其他對(duì)象有盡可能少的了解。一個(gè)類(lèi)不應(yīng)該直接與其他類(lèi)耦合,而是通過(guò)中間類(lèi)進(jìn)行通信。

          下面是一個(gè)使用C#示例來(lái)說(shuō)明迪米特法則的應(yīng)用:

          假設(shè)我們正在開(kāi)發(fā)一個(gè)社交網(wǎng)絡(luò)系統(tǒng),其中包含用戶、好友和消息等功能。我們希望能夠?qū)崿F(xiàn)用戶發(fā)送消息給好友的功能。

          首先,定義三個(gè)類(lèi) User、FriendMessage 來(lái)表示用戶、好友和消息,并在 User 類(lèi)中實(shí)現(xiàn)發(fā)送消息的方法:

          public class User
          {
              private string name;
              private List<Friend> friends;

              public User(string name)
              {
                  this.name = name;
                  this.friends = new List<Friend>();
              }

              public void AddFriend(Friend friend)
              {
                  friends.Add(friend);
              }

              public void SendMessageToFriends(string messageContent)
              {
                  Message message = new Message(messageContent);

                  foreach (Friend friend in friends)
                  {
                      friend.ReceiveMessage(message);
                  }
                  
                  Console.WriteLine($"User {name} sent a message to all friends.");
              }
          }

          public class Friend
          {
             private string name;

             public Friend(string name)
             {
                 this.name = name;
             }

             public void ReceiveMessage(Message message)
             {
                 Console.WriteLine($"Friend {name} received a message: {message.Content}");
                 // 處理接收到的消息...
             }
          }

          public class Message
          {
             public string Content { getset; }

             public Message(string content)
             {
                 Content = content;
             }
          }

          在這個(gè)例子中,User 類(lèi)表示用戶,Friend 類(lèi)表示好友,Message 類(lèi)表示消息。用戶可以添加好友,并通過(guò) SendMessageToFriends 方法向所有好友發(fā)送消息。

          使用示例:

          User user1 = new User("Alice");
          User user2 = new User("Bob");

          Friend friend1 = new Friend("Charlie");
          Friend friend2 = new Friend("David");

          user1.AddFriend(friend1);
          user2.AddFriend(friend2);

          user1.SendMessageToFriends("Hello, friends!");

          在這個(gè)示例中,用戶對(duì)象只與好友對(duì)象進(jìn)行通信,并不直接與消息對(duì)象進(jìn)行通信。這符合迪米特法則的要求,即一個(gè)對(duì)象應(yīng)該盡可能少地了解其他對(duì)象。

          通過(guò)將消息發(fā)送的責(zé)任委托給好友對(duì)象,在用戶類(lèi)中只需要調(diào)用 friend.ReceiveMessage(message) 方法來(lái)發(fā)送消息給所有好友。這樣可以降低類(lèi)之間的耦合性,并提高代碼的可維護(hù)性和靈活性。

          合成復(fù)用

          合成復(fù)用原則(Composite Reuse Principle,CRP)要求盡量使用對(duì)象組合,而不是繼承來(lái)達(dá)到復(fù)用的目的。通過(guò)將現(xiàn)有對(duì)象組合起來(lái)創(chuàng)建新的對(duì)象,可以更靈活地實(shí)現(xiàn)功能的復(fù)用和擴(kuò)展。

          下面是一個(gè)使用C#示例來(lái)說(shuō)明合成復(fù)用原則的應(yīng)用:

          假設(shè)我們正在開(kāi)發(fā)一個(gè)圖形庫(kù),其中包含各種形狀(如圓形、矩形等)。我們希望能夠?qū)崿F(xiàn)一個(gè)可以繪制多個(gè)形狀的畫(huà)板。

          首先,定義一個(gè)抽象基類(lèi) Shape 來(lái)表示圖形,并聲明抽象方法 Draw

          public abstract class Shape
          {
              public abstract void Draw();
          }

          然后,在具體的子類(lèi)中分別實(shí)現(xiàn)各種形狀。例如,創(chuàng)建 Circle 類(lèi)和 Rectangle 類(lèi)來(lái)表示圓形和矩形,并重寫(xiě)父類(lèi)中的 Draw 方法:

          public class Circle : Shape
          {
              public override void Draw()
              {
                  Console.WriteLine("Drawing a circle");
                  // 具體繪制圓形邏輯...
              }
          }

          public class Rectangle : Shape
          {
              public override void Draw()
              {
                  Console.WriteLine("Drawing a rectangle");
                  // 具體繪制矩形邏輯...
              }
          }

          接下來(lái),創(chuàng)建一個(gè)畫(huà)板類(lèi) Canvas 來(lái)管理并繪制多個(gè)圖形。在該類(lèi)中使用對(duì)象組合將多個(gè)圖形組合在一起:

          public class Canvas
          {
              private List<Shape> shapes;

              public Canvas()
              {
                  shapes = new List<Shape>();
              }

              public void AddShape(Shape shape)
              {
                  shapes.Add(shape);
              }

              public void DrawShapes()
              {
                  foreach (Shape shape in shapes)
                  {
                      shape.Draw();
                  }
                  
                  Console.WriteLine("All shapes are drawn.");
              }
          }

          在這個(gè)例子中,Canvas 類(lèi)通過(guò)對(duì)象組合的方式將多個(gè)圖形對(duì)象組合在一起,并提供了添加圖形和繪制圖形的方法。

          使用示例:

          Canvas canvas = new Canvas();

          Circle circle = new Circle();
          Rectangle rectangle = new Rectangle();

          canvas.AddShape(circle);
          canvas.AddShape(rectangle);

          canvas.DrawShapes();

          在這個(gè)示例中,我們創(chuàng)建了一個(gè)畫(huà)板對(duì)象 canvas,并向其中添加了一個(gè)圓形和一個(gè)矩形。然后調(diào)用 DrawShapes 方法來(lái)繪制所有的圖形。

          通過(guò)使用對(duì)象組合而不是繼承,我們可以更靈活地實(shí)現(xiàn)功能的復(fù)用和擴(kuò)展。例如,可以輕松地添加新的圖形類(lèi)型或修改現(xiàn)有圖形類(lèi)型的行為,而不會(huì)影響到畫(huà)板類(lèi)。這符合合成復(fù)用原則,并提高了代碼的可維護(hù)性和靈活性。

          轉(zhuǎn)自:明志德道

          鏈接:cnblogs.com/for-easy-fast/p/17762706.html







          回復(fù) 【關(guān)閉】學(xué)永久關(guān)閉App開(kāi)屏廣告
          回復(fù) 【刪除】學(xué)自動(dòng)檢測(cè)那個(gè)微信好友刪除、拉黑
          回復(fù) 【手冊(cè)】獲取3萬(wàn)字.NET、C#工程師面試手冊(cè)
          回復(fù) 【幫助】獲取100+個(gè)常用的C#幫助類(lèi)庫(kù)
          回復(fù) 【加群】加入DotNet學(xué)習(xí)交流群

          瀏覽 1159
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  涩久久久| 国产福利性爱小视频 | 极品精品 | 天天日天天干2024 | 99久久视频 |