<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>

          面對(duì)復(fù)雜業(yè)務(wù)架構(gòu),阿里架構(gòu)師是如何做的?

          共 14580字,需瀏覽 30分鐘

           ·

          2021-06-27 17:43

          大家好,我是moon哥~


          面對(duì)復(fù)雜的業(yè)務(wù)場(chǎng)景,千變?nèi)f化的客戶(hù)需求,如何以一變應(yīng)萬(wàn)變,以最小的開(kāi)發(fā)成本快速落地實(shí)現(xiàn),同時(shí)保證系統(tǒng)有著較低的復(fù)雜度,能夠保證系統(tǒng)后續(xù)de持續(xù)迭代能力,讓系統(tǒng)擁有較高的可擴(kuò)展性。

          這些是一個(gè)合格的架構(gòu)師必須修煉的基礎(chǔ)內(nèi)功,但是如何修煉這門(mén)神功???

          不要著急,慢慢看下去。學(xué)了真本事,拿了阿里、頭條的offer,女神還會(huì)遠(yuǎn)嗎!??????


          接下來(lái)我們來(lái)系統(tǒng)性匯總下,軟件架構(gòu)設(shè)計(jì)需要知曉的設(shè)計(jì)模式,主要是提煉精髓、核心設(shè)計(jì)思路、代碼示例、以及應(yīng)用場(chǎng)景等。

          CRUD很多人都會(huì),不懂設(shè)計(jì)模式也可以開(kāi)發(fā)軟件,但是當(dāng)開(kāi)發(fā)及維護(hù)大型軟件系統(tǒng)過(guò)程中就痛苦不堪,懂了人自然聽(tīng)得懂我在說(shuō)什么,不懂的人說(shuō)了你也不會(huì)懂。


          我將常用的軟件設(shè)計(jì)模式,做了匯總,目錄如下:


          考慮到內(nèi)容篇幅較大,為了便于大家閱讀,將軟件設(shè)計(jì)模式系列(共23個(gè))拆分成四篇文章,每篇文章講解六個(gè)設(shè)計(jì)模式,采用不同的顏色區(qū)分,便于快速消化記憶

          本文是首篇,主要講解單例模式、建造者模式、抽象工廠工廠方法、原型模式、適配器模式,共6個(gè)設(shè)計(jì)模式。



          1、單例模式


          定義:

          單例模式(Singleton)允許存在一個(gè)和僅存在一個(gè)給定類(lèi)的實(shí)例。它提供一種機(jī)制讓任何實(shí)體都可以訪問(wèn)該實(shí)例。

          核心思路:

          1?? 保證一個(gè)類(lèi)只有一個(gè)實(shí)例。如果該對(duì)象已經(jīng)被創(chuàng)建, 則返回已有的對(duì)象。為什么要這樣設(shè)計(jì)呢?因?yàn)槟承I(yè)務(wù)場(chǎng)景要控制共享資源 (例如數(shù)據(jù)庫(kù)或文件) 的訪問(wèn)權(quán)限。

          2?? 為該實(shí)例提供一個(gè)全局訪問(wèn)入口, 提供一個(gè)static訪問(wèn)方法。

          代碼示例:

          /**
           * @author 微信公眾號(hào):微觀技術(shù)
           */
          public class Singleton {

              private static Singleton instance = new Singleton();

              // 讓構(gòu)造函數(shù)為 private,這樣該類(lèi)就不會(huì)被實(shí)例化
              private Singleton() {}

              // 獲取唯一可用的對(duì)象
              public static Singleton getInstance() {
                  return instance;
              }
          }

          在類(lèi)中添加一個(gè)私有靜態(tài)成員變量用于保存單例實(shí)例,聲明一個(gè)公有靜態(tài)構(gòu)建方法用于獲取單例實(shí)例。

          注意事項(xiàng):

          多個(gè)業(yè)務(wù)場(chǎng)景,多個(gè)線程訪問(wèn)同一個(gè)類(lèi)實(shí)例的全局變量,頻發(fā)的寫(xiě)操作,可能會(huì)引發(fā)線程安全問(wèn)題。另外,為了防止其他對(duì)象使用單例類(lèi)的 new 運(yùn)算符,編碼時(shí)需要將默認(rèn)構(gòu)造函數(shù)設(shè)為私有。

          如果想要采用延遲初始化對(duì)象,多線程并發(fā)初始化時(shí),可能會(huì)有并發(fā)安全問(wèn)題。假如:線程A,線程B都阻塞在了獲取鎖的步驟上,其中線程A獲得鎖---實(shí)例化了對(duì)象----釋放鎖;之后線程B---獲得鎖---實(shí)例化對(duì)象,此時(shí)違反了我們單例模式的初衷。

          如何解決?

          采用雙重判空檢查。首先保證了安全,且在多線程情況下能保持高性能,第一個(gè)if判斷避免了其他無(wú)用線程競(jìng)爭(zhēng)鎖造成性能浪費(fèi),第二個(gè)if判斷能攔截除第一個(gè)獲得對(duì)象鎖線程以外的線程。

          /**
           * @author 微信公眾號(hào):微觀技術(shù)
           */
          public class SingleonLock {

              private static SingleonLock doubleLock;

              private SingleonLock() {}

              // 雙重校驗(yàn)鎖
              public static SingleonLock getInstance() {
                  if (doubleLock == null) {
                      synchronized (SingleonLock.class) {
                          if (doubleLock == null) {
                              doubleLock = new SingleonLock();
                          }
                      }
                  }
                  return doubleLock;
              }
          }


          2、建造者模式


          定義:

          建造者模式,也稱(chēng) Builder 模式。

          將復(fù)雜對(duì)象的構(gòu)造與其表示分離,以便同一構(gòu)造過(guò)程可以創(chuàng)建不同的表示。

          簡(jiǎn)單來(lái)說(shuō),建造者模式就是如何一步步構(gòu)建一個(gè)包含多個(gè)組成部件的對(duì)象,相同的構(gòu)建過(guò)程可以創(chuàng)建不同的產(chǎn)品

          核心思路:


          角色類(lèi)別說(shuō)明
          Builder接口或抽象類(lèi)抽象的建造者,不是必須的
          ConcreteBuilder具體的建造者可以有多個(gè)「因?yàn)槊總€(gè)建造風(fēng)格可能不一樣」,必須要有
          Product普通類(lèi)最終構(gòu)建的對(duì)象,必須要有
          Director指揮者統(tǒng)一指揮建造者去建造目標(biāo),不是必須的

          代碼示例:

          /**
           * @author 微信公眾號(hào):微觀技術(shù)
           */
          public class Person {
              private String name;
              private int age;
              private String address;

              public static PersonBuilder builder() {
                  return new PersonBuilder();
              }

              private Person(PersonBuilder builder) {
                  this.name = builder.name;
                  this.age = builder.age;
                  this.address = builder.address;
              }

              // 建造者
              static class PersonBuilder {

                  private String name;
                  private int age;
                  private String address;

                  public PersonBuilder() {
                  }

                  public PersonBuilder name(String name) {
                      this.name = name;
                      return this;
                  }

                  public PersonBuilder age(int age) {
                      this.age = age;
                      return this;
                  }

                  public PersonBuilder address(String address) {
                      this.address = address;
                      return this;
                  }

                  public Person build() {
                      return new Person(this);
                  }
              }

          }


          • Person 中創(chuàng)建一個(gè)靜態(tài)內(nèi)部類(lèi) PersonBuilder,然后將 Person 中的參數(shù)都復(fù)制到 PersonBuilder類(lèi)中。
          • Person中創(chuàng)建一個(gè)private的構(gòu)造函數(shù),入?yún)?PersonBuilder類(lèi)型
          • PersonBuilder中創(chuàng)建一個(gè)public的構(gòu)造函數(shù)
          • PersonBuilder中創(chuàng)建設(shè)置函數(shù),對(duì)Person 中那些可選參數(shù)進(jìn)行賦值,返回值為PersonBuilder類(lèi)型的實(shí)例
          • PersonBuilder中創(chuàng)建一個(gè)build()方法,在其中構(gòu)建Person 的實(shí)例并返回

          /**
           * @author 微信公眾號(hào):微觀技術(shù)
           */
          public class PersonBuilderTest {

              public static void main(String[] args) {
                  Person person = Person.builder()
                          .name("Tom哥")
                          .age(18)
                          .address("杭州")
                          .build();
                  System.out.println(JSON.toJSONString(person));
              }

          }

          客戶(hù)端使用鏈?zhǔn)秸{(diào)用,一步一步的把對(duì)象構(gòu)建出來(lái)。

          適用場(chǎng)景:

          • 分階段、分步驟的方法更適合多次運(yùn)算結(jié)果類(lèi)創(chuàng)建場(chǎng)景。比如創(chuàng)建一個(gè)類(lèi)實(shí)例的參數(shù)并不會(huì)一次準(zhǔn)備好,有些參數(shù)可能需要調(diào)用多個(gè)服務(wù)運(yùn)算后才能拿得到,這時(shí),我們可以根據(jù)已知參數(shù),預(yù)先對(duì)類(lèi)進(jìn)行創(chuàng)建,待后續(xù)的參數(shù)準(zhǔn)備好了后,再設(shè)置。
          • 不關(guān)心特定類(lèi)型的建造者的具體算法實(shí)現(xiàn)。比如,我們并不關(guān)心StringBuilder的具體代碼實(shí)現(xiàn),只關(guān)心它提供了字符串拼接功能。


          使用建造者模式能更方便地幫助我們按需進(jìn)行對(duì)象的實(shí)例化,避免寫(xiě)很多不同參數(shù)的構(gòu)造函數(shù),同時(shí)還能解決同一類(lèi)型參數(shù)只能寫(xiě)一個(gè)構(gòu)造函數(shù)的弊端。


          最后,實(shí)際項(xiàng)目中,為了簡(jiǎn)化編碼,通??梢灾苯邮褂?/span>lombok@Builder 注解實(shí)現(xiàn)類(lèi)自身的建造者模式。


          3、抽象工廠模式


          定義:

          抽象工廠模式圍繞一個(gè)超級(jí)工廠創(chuàng)建其他工廠,又稱(chēng)為其他工廠的工廠。是一種創(chuàng)建型設(shè)計(jì)模式,它能創(chuàng)建一系列相關(guān)的對(duì)象,而無(wú)需指定其具體類(lèi)。

          抽象工廠模式的關(guān)鍵點(diǎn):如何找到正確的抽象。

          對(duì)于軟件調(diào)用者來(lái)說(shuō),他們更關(guān)心軟件提供了什么功能。至于內(nèi)部如何實(shí)現(xiàn)的,他們并不關(guān)心。另外,考慮到安全問(wèn)題,一般內(nèi)部具體的實(shí)現(xiàn)細(xì)節(jié)通常會(huì)隱藏掉。

          我們以電視、冰箱、洗衣機(jī)等家用電器生產(chǎn)為例,很多廠商像Haier、Sony、小米、Hisense等能生產(chǎn)上述電器,不過(guò)在外觀、性能、功率、智能化、特色功能等方面會(huì)有差異。面對(duì)這樣的需求,我們?nèi)绾谓柚?/span>抽象工廠模式來(lái)實(shí)現(xiàn)編碼。

          抽象工廠模式體現(xiàn)為定義一個(gè)抽象工廠類(lèi),多個(gè)不同的具體工廠繼承這個(gè)抽象工廠類(lèi)后,再各自實(shí)現(xiàn)相同的抽象功能,從而實(shí)現(xiàn)代碼上的多態(tài)性。

          代碼示例:

          /**
           * @author 微信公眾號(hào):微觀技術(shù)
           */
          public abstract class AbstractFactory {
              // 生產(chǎn)電視
              abstract Object createTV();
              // 生產(chǎn)洗衣機(jī)
              abstract Object createWasher();
              // 生產(chǎn)冰箱
              abstract Object createRefrigerator();

          }

          public class HaierFactory extends AbstractFactory {
              @Override
              Object createTV() {
                  return null;
              }

              @Override
              Object createWasher() {
                  return null;
              }

              @Override
              Object createRefrigerator() {
                  return null;
              }
          }


          public class XiaomiFactory extends AbstractFactory {
              @Override
              Object createTV() {
                  return null;
              }

              @Override
              Object createWasher() {
                  return null;
              }

              @Override
              Object createRefrigerator() {
                  return null;
              }
          }

          AbstractFactory是抽象工廠類(lèi),能夠創(chuàng)建電視、洗衣機(jī)、冰箱抽象產(chǎn)品;而HaierFactoryXiaomiFactory 是具體的工廠,負(fù)責(zé)生產(chǎn)具體的產(chǎn)品。當(dāng)我們要生產(chǎn)具體的產(chǎn)品時(shí),只需要告訴AbstractFactory即可。

          解決問(wèn)題:

          • 對(duì)于不同產(chǎn)品系列有比較多共性特征時(shí),可以使用抽象工廠模式,有助于提升組件的復(fù)用性。
          • 當(dāng)需要提升代碼的擴(kuò)展性并降低維護(hù)成本時(shí),把對(duì)象的創(chuàng)建和使用過(guò)程分開(kāi),能有效地將代碼統(tǒng)一到一個(gè)級(jí)別上。

          適用場(chǎng)景:

          • 解決跨平臺(tái)兼容性的問(wèn)題。當(dāng)一個(gè)應(yīng)用程序需要支持Windows、Mac、Linux等多套操作系統(tǒng)。
          • 電商的商品、訂單、物流系統(tǒng),需要根據(jù)區(qū)域政策、用戶(hù)的購(gòu)買(mǎi)習(xí)慣,差異化處理
          • 不同的數(shù)據(jù)庫(kù)產(chǎn)品,JDBC 就是對(duì)于數(shù)據(jù)庫(kù)增刪改查建立的抽象工廠類(lèi),無(wú)論使用什么類(lèi)型的數(shù)據(jù)庫(kù),只要具體的數(shù)據(jù)庫(kù)組件能夠支持 JDBC,就能對(duì)數(shù)據(jù)庫(kù)進(jìn)行讀寫(xiě)操作。


          4、工廠方法模式


          工廠方法模式與抽象工廠模式類(lèi)似。工廠方法模式因?yàn)橹粐@著一類(lèi)接口來(lái)進(jìn)行對(duì)象的創(chuàng)建與使用,使用場(chǎng)景更加單一,項(xiàng)目中更常見(jiàn)些。

          定義

          定義一個(gè)創(chuàng)建對(duì)象的接口,讓其子類(lèi)自己決定實(shí)例化哪一個(gè)類(lèi),工廠模式使其創(chuàng)建過(guò)程延遲到子類(lèi)進(jìn)行。

          核心點(diǎn):封裝對(duì)象創(chuàng)建的過(guò)程,提升創(chuàng)建對(duì)象方法的可復(fù)用性。

          工廠方法模式包含三個(gè)關(guān)鍵角色:抽象產(chǎn)品、具體產(chǎn)品、工廠類(lèi)。

          定義一個(gè)抽象產(chǎn)品接口ITVHaierTVXiaomiTV是具體產(chǎn)品類(lèi),TVFactory是工廠類(lèi),負(fù)責(zé)生產(chǎn)具體的對(duì)象實(shí)例。

          代碼示例:

          /**
           * @author 微信公眾號(hào):微觀技術(shù)
           */
          public interface ITV {
              // 描述
              Object desc();
          }

          public class HaierTV implements ITV {
              @Override
              public Object desc() {
                  return "海爾電視";
              }
          }

          public class XiaomiTV implements ITV {
              @Override
              public Object desc() {
                  return "小米電視";
              }
          }

          public class TVFactory {
              public static ITV getTV(String name) {
                  switch (name) {
                      case "haier":
                          return new HaierTV();
                      case "xiaomi":
                          return new XiaomiTV();
                      default:
                          return null;
                  }
              }
          }

          public class Client {
              public static void main(String[] args) {
                  ITV tv = TVFactory.getTV("xiaomi");
                  Object result = tv.desc();
                  System.out.println(result);
              }
          }

          工廠方法模式是圍繞著特定的抽象產(chǎn)品(接口)來(lái)封裝對(duì)象的創(chuàng)建過(guò)程,Client只需要通過(guò)工廠類(lèi)來(lái)創(chuàng)建具體對(duì)象實(shí)例,然后就可以使用其功能。

          工廠方法模式將對(duì)象的創(chuàng)建和使用過(guò)程分開(kāi),降低代碼耦合性。


          5、原型模式


          原型模式是創(chuàng)建型模式的一種,其特點(diǎn)在于通過(guò)“復(fù)制”一個(gè)已經(jīng)存在的實(shí)例來(lái)返回新的實(shí)例,而不是新建實(shí)例。被復(fù)制的實(shí)例就是我們所稱(chēng)的“原型”,這個(gè)原型是可定制的。

          定義:

          使用原型實(shí)例指定創(chuàng)建對(duì)象的種類(lèi),然后通過(guò)拷貝這些原型來(lái)創(chuàng)建新的對(duì)象。

          代碼示例:

          /**
           * @author 微信公眾號(hào):微觀技術(shù)
           */
          public interface Prototype extends Cloneable {
              public Prototype clone() throws CloneNotSupportedException;
          }

          public class APrototype implements Prototype {
              @Override
              public Prototype clone() throws CloneNotSupportedException {
                  System.out.println("開(kāi)始克隆《微觀技術(shù)》對(duì)象");
                  return (APrototype) super.clone();
              }
          }

          public class Client {
              @SneakyThrows
              public static void main(String[] args) {
                  Prototype a = new APrototype();
                  Prototype b = a.clone();
                  System.out.println("a的對(duì)象引用:" + a);
                  System.out.println("b的對(duì)象引用:" + b);
              }
          }

          執(zhí)行結(jié)果:

          開(kāi)始克隆《微觀技術(shù)》對(duì)象
          a的對(duì)象引用:course.p14.p5.APrototype@7cc355be
          b的對(duì)象引用:course.p14.p5.APrototype@6e8cf4c6

          打印出兩個(gè)對(duì)象的地址,發(fā)現(xiàn)不相同,在內(nèi)存中為兩個(gè)對(duì)象。

          Cloneable 接口本身是空方法,調(diào)用的 clone() 方法其實(shí)是 Object.clone() 方法

          優(yōu)點(diǎn):

          • 性能優(yōu)良。不用重新初始化對(duì)象,而是動(dòng)態(tài)地獲取對(duì)象運(yùn)行時(shí)的狀態(tài)。
          • 可以擺脫構(gòu)造函數(shù)的約束。

          特別注意:

          clone()淺復(fù)制,也就是基本類(lèi)型數(shù)據(jù),會(huì)給你重新復(fù)制一份新的。但是引用類(lèi)型(對(duì)象中包含對(duì)象),他就不會(huì)重新復(fù)制份新的。引用類(lèi)型如:bean實(shí)例引用、集合等一些引用類(lèi)型。

          如何解決?

          你需要在執(zhí)行完super.clone() 獲得淺復(fù)制對(duì)象后,再手動(dòng)對(duì)其中的全局變量重新構(gòu)造對(duì)象并賦值。當(dāng)然,經(jīng)過(guò)這個(gè)過(guò)程,得到的對(duì)象我們稱(chēng)之為深復(fù)制。

          適用場(chǎng)景:

          • 反序列化,比如 fastjson的JSON.parseObject() ,將字符串轉(zhuǎn)變?yōu)閷?duì)象
          • 每次創(chuàng)建新對(duì)象資源損耗較大
          • 對(duì)象中的屬性非常多,通過(guò)get和set方法創(chuàng)建對(duì)象,復(fù)制黏貼非常痛苦

          加餐:

          Spring 框架中提供了一個(gè)工具類(lèi),BeanUtils.copyProperties 可以方便的完成對(duì)象屬性的拷貝,其實(shí)也是淺復(fù)制,只能對(duì)基本類(lèi)型數(shù)據(jù)、對(duì)象引用拷貝。使用時(shí)特別要注意,如果全局變量有對(duì)象類(lèi)型,原型對(duì)象和克隆的對(duì)象會(huì)二次修改,要特殊處理,采用深復(fù)制,否則會(huì)引發(fā)安全問(wèn)題。


          6、適配器模式


          我們都知道美國(guó)的電壓是110V,而中國(guó)是220V,如果你去要美國(guó)旅行時(shí),一定要記得帶電源適配器,將不同國(guó)家使用的電源電流標(biāo)準(zhǔn)轉(zhuǎn)化為適合我們自己電器的標(biāo)準(zhǔn),否則很容易燒壞電子設(shè)備。

          定義:

          將類(lèi)的接口轉(zhuǎn)換為客戶(hù)期望的另一個(gè)接口,適配器可以讓不兼容的兩個(gè)類(lèi)一起協(xié)同工作。核心點(diǎn)在于轉(zhuǎn)換!

          核心思路:

          在原有的接口或類(lèi)的外層封裝一個(gè)新的適配器層,以實(shí)現(xiàn)擴(kuò)展對(duì)象結(jié)構(gòu)的效果,并且這種擴(kuò)展可以無(wú)限擴(kuò)展下去。

          • Adaptee:源接口,需要適配的接口
          • Target:目標(biāo)接口,暴露出去的接口
          • Adapter:適配器,將源接口適配成目標(biāo)接口

          適用場(chǎng)景:

          • 原有接口無(wú)法修改時(shí),又必須快速兼容部分新功能
          • 需要依賴(lài)外部系統(tǒng)時(shí),一般會(huì)單獨(dú)封裝防腐層,降低外部系統(tǒng)的突發(fā)風(fēng)險(xiǎn)帶來(lái)的影響
          • 適配不同數(shù)據(jù)格式,不同接口協(xié)議轉(zhuǎn)換
          • 舊接口過(guò)渡升級(jí)

          案例:

          比如查物流信息,由于物流公司的系統(tǒng)都是各自獨(dú)立,在編程語(yǔ)言和交互方式上有很大差異,需要針對(duì)不同的物流公司做單獨(dú)適配,同時(shí)結(jié)合不同公司的系統(tǒng)性能,配置不同的響應(yīng)超時(shí)時(shí)間


          適配器模式號(hào)稱(chēng)為“最好用打補(bǔ)丁模式”,就是因?yàn)橹灰且粋€(gè)接口,都可以用它來(lái)進(jìn)行適配。


          寫(xiě)在最后


          設(shè)計(jì)模式很多人都學(xué)習(xí)過(guò),但項(xiàng)目實(shí)戰(zhàn)時(shí)總是暈暈乎乎,原因在于沒(méi)有了解其核心是什么,底層邏輯是什么,《設(shè)計(jì)模式:可復(fù)用面向?qū)ο蟮幕A(chǔ)》有講過(guò),

          在設(shè)計(jì)中思考什么應(yīng)該變化,并封裝會(huì)發(fā)生變化的概念。

          軟件架構(gòu)的精髓:找到變化,封裝變化。

          業(yè)務(wù)千變?nèi)f化,沒(méi)有固定的編碼答案,千萬(wàn)不要硬套設(shè)計(jì)模式。無(wú)論選擇哪一種設(shè)計(jì)模式,盡量要能滿足SOLID原則,自我review是否滿足業(yè)務(wù)的持續(xù)擴(kuò)展性。有句話說(shuō)的好,“不論白貓黑貓,能抓老鼠就是好貓?!?/span>




            關(guān)于我:前阿里架構(gòu)師,出過(guò)專(zhuān)利,競(jìng)賽拿過(guò)獎(jiǎng),CSDN博客專(zhuān)家,負(fù)責(zé)過(guò)電商交易、社區(qū)生鮮、營(yíng)銷(xiāo)、金融等業(yè)務(wù),多年團(tuán)隊(duì)管理經(jīng)驗(yàn),愛(ài)思考,喜歡結(jié)交朋友

            「點(diǎn)擊西方關(guān)注」,拉你進(jìn)群,BAT大廠大神技術(shù)交流

            推薦閱讀


            面試題:mysql 一棵 B+ 樹(shù)能存多少條數(shù)據(jù)?

            學(xué)會(huì)這10個(gè)設(shè)計(jì)原則,離架構(gòu)師又進(jìn)了一步?。?!

            億級(jí)系統(tǒng)的Redis緩存如何設(shè)計(jì)???

            【高并發(fā)、高性能、高可用】系統(tǒng)設(shè)計(jì)經(jīng)驗(yàn)

            人人都是架構(gòu)師???談何容易??!

            【萬(wàn)級(jí)并發(fā)】電商庫(kù)存扣減如何設(shè)計(jì)?不超賣(mài)!

            瀏覽 37
            點(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>
                    欧美成人免费一级人片100 | 亚洲国产精品久久久久久6q | 五月激情视频 | 黄色网页69 | 操逼视频。 |