Java實現23種設計模式教程(3)

      網友投稿 732 2022-05-30

      要實現如上的結果,我們這次不用靜態代理,而是用JDK動態代理

      其實所謂的動態代理,也就是不用寫代理類了,而是又JDK底層通過反射在內存中幫你創建好了一個代理類

      public class logger implements loggers { /** * JDK動態代理: * 我們無需創建代理類,而是有JDK底層的反射幫我們在內存中自動創建 */ @Override public void writerlogger() { System.out.println("寫入日志。。"); } }

      public interface loggers { void writerlogger(); }

      動態代理:

      public class loggerProxyMain { private static logger logger=new logger(); public static void main(String[] args) { /** * public static Object newProxyInstance(ClassLoader loader, * Class[] interfaces, * InvocationHandler h) */ loggers loggers= (com.design.proxy.dongtaiProxy.loggers) Proxy.newProxyInstance(logger.class.getClassLoader(), logger.class.getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { /* 第一個參數:被代理的類的對象 第二個參數:方法參數args */ System.out.println("代理開始===="); //如果用代理實例調用方法,將會在這里執行 Object invoke = method.invoke(logger, args);//不返回這個對象的話,代理實例為null System.out.println("代理結束"); return invoke; //返回代理實例,并返回到loggers對象中 } }); //****注意:進入invoke方法是有前提的,就是我們要使用代理實例對象loggers,如果不使用它就不會進入到invoke方法中 //輸入logger對象也行,也可以讓他進入invoke方法 // System.out.println(loggers); /* 當我們去調用代理的方法時,method.invoke就會監聽到,并執行被代理的方法 */ loggers.writerlogger(); } }

      裝飾器模式

      我們可以把裝飾器分為主菜和配菜,配菜就是裝飾器,而主菜就是被裝飾的

      公式:創建一個抽象類(作為被裝飾者的父類),被裝飾者類去繼承它,然后創建裝飾者抽象類并繼承被裝飾者的父類,再有裝飾者子類去繼承裝飾者抽象類。

      案例:

      被裝飾者的抽象類,在這里是最高的類

      public abstract class breakFast { public abstract int cost(); //價格 }

      被裝飾者具體類

      public class rice extends breakFast { /** * 主食:米飯 */ @Override public int cost() { return 5; } }

      public class noodles extends breakFast { /** *主食: 面條 */ @Override public int cost() { return 10; } }

      裝飾者抽象類:繼承與被裝飾者的父類

      public abstract class decorations extends breakFast{ public abstract int cost(); //裝飾者的錢 }

      裝飾者類

      public class coke extends decorations { private breakFast breakFast; private final int COKE_COST=2; //coke的價格 public coke(breakFast breakFast){ this.breakFast=breakFast; } @Override public int cost() { return breakFast.cost()+COKE_COST; } }

      public class milk extends decorations { private breakFast breakFast; private final int MILK_COST=3; //milk的價格 public milk(breakFast breakFast){ this.breakFast=breakFast; } @Override public int cost() { return breakFast.cost()+MILK_COST; } }

      測試:

      public class main { public static void main(String[] args) { rice rice = new rice(); //創建被裝飾者對象 milk milk = new milk(rice);//把被裝飾者對象放到裝飾者的構造方法上去 System.out.println("rice:"+rice.cost()); System.out.println("milk+rice:"+milk.cost()); milk milk1 = new milk(milk); System.out.println("milk*2+rice"+milk1.cost()); } }

      適配器模式

      適配器模式:就是把原本互不兼容的兩樣東西或者格式,轉換成可以兼容

      比如說:家用電壓是220v,但是我們手機充電不需要這么大的電壓,我們這時候需要電源適配器(充電頭),去適配這個電壓,把220v適配成(比如:5v,11v等等)

      再比如說:有一個方法只能接收int類型數據,但是我們接收到了一個String類型數據,int和String本身就是兩個不相同的類型,所以說這個方法是接收不到String類型的,我們可以使用適配器,把String類型轉換(適配)成int類型,這樣這個方法就可以接收到這個String類型數據了。

      公式:適配器類要繼承src(原來的類),并實現dest(目標)接口

      首先創建適配器類,并運用上面的公式:

      public class classAdapter extends srcClass implements destInterface{ /** * 類適配器是有公式的 * 公式:類適配器要繼承源類,實現于目標接口 * public class classAdapter extends srcClass implements destInterface * * srcClass:在這里是指家用電壓220V * destInterface : 在這里是指我們想適配成多少v的電壓,比如手機常用的電壓 5v */ @Override public int vivoBattery_5V() { int src = super.getSrc(); int dest=src/44; return dest; } }

      源(src)類:

      public class srcClass { private final int v=220; //家用電壓 //源類生成220v public int getSrc(){ return v; } }

      目標接口:

      public interface destInterface { int vivoBattery_5V(); //vivo手機想要多少伏的電壓 }

      測試:

      public class Test { public static void main(String[] args) { classAdapter classAdapter = new classAdapter(); int res = classAdapter.vivoBattery_5V(); System.out.println("當前電壓:"+res+"v"); } }

      為什么會有對象適配器:我們的對象適配器都是在類適配器上優化的,類適配器的缺點是extends(繼承),因為Java是單繼承的,而我們的對象適配器不過就是把這個extends srcClass 優化成一個對象,通過構造器進行傳入,然后通過這個對象進行調用srcClass的方法,而類適配器就是通過super關鍵字去調用方法。。

      public class adapter implements destInterface { private srcClass srcClass; //把之前的類適配器的extends 源類,改成一個對象進行調用 public adapter(srcClass srcClass){ //再通過構造器傳入srcClass對象 this.srcClass=srcClass; } @Override public int get10V() { int src = srcClass.getV(); int dest=src/22; return dest; } }

      public interface destInterface { int get10V(); }

      public class srcClass { private final int v=220; public int getV(){ return v; } }

      public class Test { public static void main(String[] args) { adapter adapter = new adapter(new srcClass()); int v = adapter.get10V(); System.out.println(v); } }

      為何有接口適配器:我們上面說的兩種適配器方式都有一個缺點:就是我們上面兩種適配器都需要實現目標接口,當目標接口有多個適配方法時,我們都要對它進行實現,而我們不需要全部實現,只需要實現其中一個即可,我們的接口適配器就是為了解決這個問題的。

      沒有給接口方法默認實現時:

      public interface dest { int adapter_5v(); int adapter_10v(); int adapter_20v(); }

      public class adapter implements dest { @Override public int adapter_5v() { return 0; } @Override public int adapter_10v() { return 0; } @Override public int adapter_20v() { return 0; } }

      就需要全部進行實現,很復雜

      public class srcClass { private final int v=220; //家用電壓 //源類生成220v public int getSrc(){ return v; } }

      public interface dest { /** * 當接口適配的方法很多,但是我們不需要全部的進行實現,我們可以隨便給他一個默認值,用default修飾 * 當我們需要具體實現某個方法時,只需要重寫對應的方法即可 */ default int adapter_5v(){ return 0; } default int adapter_10v(){ return 0; } default int adapter_20v(){ return 0; } }

      public class adapter implements dest { private srcClass srcClass; public adapter(srcClass srcClass){ this.srcClass=srcClass; } @Override public int adapter_10v() { int src = srcClass.getSrc(); int res=src/22; return res; } }

      class main{ public static void main(String[] args) { adapter adapter = new adapter(new srcClass()); int i = adapter.adapter_10v(); System.out.println(i); } }

      享元模式

      享元模式:“享”是共享 ,“元”是對象 ,享元模式也就是一種利用共享技術對實例對象進行共享,提高實例對象的復用性,和節省資源的開銷,減少對象的創建,應用在大量的“”相似“”對象,但是這些對象只有一些不同,我們可以用這個模式。

      享元模式如何在定制相似的對象(對對象的數據進行修改):我們可以通過享元模式的簡單工廠從HashMap/HashTable中get到,然后再用set方法對它進行定制。

      何為相似的對象: 說白了也就是同一個類創建出來的對象就是相似的對象

      案例:用戶的網站界面屬性(網站類型(type)、顏色(color),動態消息(message))

      public abstract class website { /** * 總的網站抽象類 */ public abstract void setColor(String color); public abstract void setMessages(List messages); public abstract void setRandomCode(String randomCode); }

      public class sina extends website { /** * 新浪網站 */ private final String type="新浪"; private String color; private List messages; private String randomCode; //隨機碼 public sina() { } public String getType() { return type; } public String getColor() { return color; } public List getMessages() { return messages; } public String getRandomCode() { return randomCode; } @Override public String toString() { return "sina{" + "type='" + type + '\'' + ", color='" + color + '\'' + ", messages=" + messages + ", randomCode='" + randomCode + '\'' + '}'; } @Override public void setColor(String color) { this.color=color; } @Override public void setMessages(List messages) { this.messages=messages; } @Override public void setRandomCode(String randomCode) { this.randomCode=randomCode; } }

      public class zhihu extends website { /** * 知乎 */ private final String type="知乎"; private String color; private List messages; private String randomCode; public zhihu() { } public String getType() { return type; } public String getColor() { return color; } public List getMessages() { return messages; } public String getRandomCode() { return randomCode; } @Override public String toString() { return "zhihu{" + "type='" + type + '\'' + ", color='" + color + '\'' + ", messages=" + messages + ", randomCode='" + randomCode + '\'' + '}'; } @Override public void setColor(String color) { this.color=color; } @Override public void setMessages(List messages) { this.messages=messages; } @Override public void setRandomCode(String randomCode) { this.randomCode=randomCode; } }

      享元工廠(相當于簡單工廠的升級版):

      這邊存在線程安全問題,因為getWebsiteByFactory方法不是原子操作,所以我們多線程環境下一定要加鎖

      public class simpleFactory { /** * 享元模式是需要簡單工廠模式的 */ private Map map=new HashMap<>(); //享元模式精髓 private String[] colors={"red","blue","yellow","green","orange"}; public website getWebsiteByFactory(String type){ if(type==null||type.equals("")) { return null; }else { website website = map.get(type); if(website==null){ //用簡單工廠模式來書寫 if(type.equals("新浪")){ sina sina = new sina(); Random random = new Random(); int index = random.nextInt(5); sina.setColor(colors[index]); int i = random.nextInt(1000); ArrayList list = new ArrayList<>(); list.add("hello"+i); sina.setMessages(list); sina.setRandomCode(String.valueOf(random.nextInt(9999))); map.put(type,sina); System.out.println("創建新浪網站對象成功"); return sina; }else if(type.equals("知乎")){ zhihu zhihu = new zhihu(); Random random = new Random(); zhihu.setColor(colors[random.nextInt(5)]); ArrayList list = new ArrayList<>(); list.add("hello"+random.nextInt(1000)); zhihu.setMessages(list); zhihu.setRandomCode(String.valueOf(random.nextInt(9999))); map.put(type,zhihu); System.out.println("創建知乎網站成功"); return zhihu; }else { return null; } }else { System.out.println("在享元模式的簡單工廠中已經存在這個網站,所以直接獲取到,沒有重新創建對象"); return website; } } } }

      測試:

      public class main { private static final String[] websites={"新浪","知乎"}; public static void main(String[] args) { simpleFactory simpleFactory = new simpleFactory(); //創建享元模式的簡單工廠 website s1 = simpleFactory.getWebsiteByFactory("新浪"); System.out.println(s1); //會創建對象 /** * 享元模式重要作用之一:定制對象 */ s1.setColor("利用享元模式定制對象"); website s2 = simpleFactory.getWebsiteByFactory("新浪"); System.out.println(s2); //不會創建對象,而是從map里面拿 Random random = new Random(); // for (int i = 0; i < 20; i++) { // new Thread(()->{ // website website = simpleFactory.getWebsiteByFactory(websites[random.nextInt(2)]); // System.out.println(website); // // }).start(); // } } }

      輸出結果:

      創建新浪網站對象成功 sina{type='新浪', color='red', messages=[hello713], randomCode='2522'} 在享元模式的簡單工廠中已經存在這個網站,所以直接獲取到,沒有重新創建對象 sina{type='新浪', color='利用享元模式定制對象', messages=[hello713], randomCode='2522'}

      只需在getWebsiteByFactory方法上加鎖即可

      public class simpleFactory { /** * 享元模式是需要簡單工廠模式的 */ private Map map=new HashMap<>(); //享元模式精髓 private String[] colors={"red","blue","yellow","green","orange"}; public synchronized website getWebsiteByFactory(String type){

      組合模式(樹型結構)

      組合模式的項目應用:實現多級菜單 、文件夾的管理

      組合模式我們把它看成一種“樹”型結構,固然后面我們在打印這些內容的時候是需要用遞歸的

      Java實現23種設計模式教程(3)

      因為組合模式是按照樹形結構來組合的,所以也有樹的特點(比如:葉子節點)

      案例:利用組合模式來實現三級菜單。

      定義組合模式的菜單組件接口,并定義添加、刪除、展示結點方法:

      public interface component { /** * 組件接口:所有菜單都要實現這個component(組件)接口 * 組合模式所需方法:添加結點、刪除結點、打印菜單 */ //需要給這個添加結點一個默認實現,因為我們的葉子結點不需要添加結點和刪除結點這兩個方法 default void addNode(component component){ throw new UnsupportedOperationException();//默認拋出不支持操作異常 } default void deleteNode(component component){ throw new UnsupportedOperationException(); } //打印===都需要實現 void showMenu(); }

      菜單組件實現類(非葉子結點==第一、二級菜單):

      一級菜單:

      public class firstMenu implements component { /** * 一級菜單 */ private String name; //菜單名稱 private List components; public firstMenu(String name){ this.name=name; this.components=new ArrayList<>(); } @Override public void addNode(component component) { components.add(component); } @Override public void deleteNode(component component) { components.remove(component); } @Override public void showMenu() { System.out.println("---"+this.getName()); //打印當前調用者的名稱 if(components.size()>0){ for (component component : components) { component.showMenu(); //遞歸的調用這個showMenu方法 } } } public String getName() { return name; } public void setName(String name) { this.name = name; } public List getComponents() { return components; } public void setComponents(List components) { this.components = components; } }

      二級菜單:

      public class secondMenu implements component { /** * 二級菜單 */ private String name; private List components; public secondMenu(String name){ this.name=name; this.components=new ArrayList<>(); } @Override public void addNode(component component) { components.add(component); } @Override public void deleteNode(component component) { components.remove(component); } @Override public void showMenu() { System.out.println("------"+this.getName()); if(components.size()>0){ for (component component : components) { component.showMenu();; } } } public String getName() { return name; } public void setName(String name) { this.name = name; } public List getComponents() { return components; } public void setComponents(List components) { this.components = components; } }

      三級菜單:(葉子節點),沒有添加、刪除結點方法

      public class lastMenu implements component { private String name; /** * 最后一個菜單(三級菜單):不能添加和刪除,因為它是樹的葉子結點 */ public lastMenu(String name){ this.name=name; } @Override public void showMenu() { System.out.println("---------"+this.name); } }

      組合模式客戶端代碼:

      public class client { /** * 組合模式客戶端 * @param args */ public static void main(String[] args) { //創建一級菜單 component f1=new firstMenu("用戶列表"); //創建二級菜單 component s1=new secondMenu("用戶信息"); component s2=new secondMenu("用戶權限"); component s3=new secondMenu("用戶好友"); //創建三級菜單 component l1=new lastMenu("信息修改"); component l2=new lastMenu("信息刪除"); component l3=new lastMenu("修改權限"); component l4=new lastMenu("添加好友"); component l5=new lastMenu("刪除好友"); component l6=new lastMenu("修改好友信息"); //進行組合 f1.addNode(s1); f1.addNode(s2); f1.addNode(s3); s1.addNode(l1); s1.addNode(l2); s2.addNode(l3); s3.addNode(l4); s3.addNode(l5); s3.addNode(l6); //展示菜單 f1.showMenu(); } }

      輸出結果:

      ---用戶列表 ------用戶信息 ---------信息修改 ---------信息刪除 ------用戶權限 ---------修改權限 ------用戶好友 ---------添加好友 ---------刪除好友 ---------修改好友信息

      外觀模式

      為什么會有外觀模式?外觀模式能解決什么?其實就是把其他對象調用方法封裝到外觀類上,我們只需要通過調用外觀類的方法就可以調用其他類的方法

      總結:外觀模式(門面模式)說白了就是把多個不同對象(類)的方法歸納到一個門面類(外觀類)中,這樣省去頻繁創建對象,核心就是門面類

      使用兩種方法實現案例“買水果問題”。。

      蘋果實體類:

      public class apple { /** * 蘋果實體類 */ private String id; private String name; public apple(String name){ this.name=name; } public void setId(String id) { this.id = id; } public String getName() { return name; } @Override public String toString() { return "apple{" + "id='" + id + '\'' + ", name='" + name + '\'' + '}'; } }

      public class banana { /** * 香蕉實體類 */ private String id; private String name; public banana(String name){ this.name=name; } public void setId(String id) { this.id = id; } public String getName() { return name; } @Override public String toString() { return "banana{" + "id='" + id + '\'' + ", name='" + name + '\'' + '}'; } }

      public class orange { /** * 橙子實體類 */ private String id; private String name; public orange(String name){ this.name=name; } public void setId(String id) { this.id = id; } public String getName() { return name; } @Override public String toString() { return "orange{" + "id='" + id + '\'' + ", name='" + name + '\'' + '}'; } }

      創建各自的商店:

      public class appleStore { /** * 蘋果專賣店 */ //買蘋果 public apple buyApple(){ apple apple = new apple("蘋果"); apple.setId(UUID.randomUUID().toString().replaceAll("-","")); return apple; } }

      public class bananaStore { //香蕉實體店 public banana buyBanana(){ banana banana = new banana("香蕉"); banana.setId(UUID.randomUUID().toString().replaceAll("-","")); return banana; } }

      public class orangeStore { //橙子實體店 public orange buyOrange(){ orange orange=new orange("橙子"); orange.setId(UUID.randomUUID().toString().replaceAll("-","")); return orange; } }

      顧客買水果:

      public class client { public static void main(String[] args) { //買蘋果 //1.創建蘋果店對象 appleStore appleStore = new appleStore(); //2.購買 apple apple = appleStore.buyApple(); //買香蕉 bananaStore bananaStore = new bananaStore(); banana banana = bananaStore.buyBanana(); //買橙子 orangeStore orangeStore = new orangeStore(); orange orange = orangeStore.buyOrange(); System.out.println(apple); System.out.println(banana); System.out.println(orange); } }

      ====================

      總結:可以看出來使用傳統方法買水果比較復雜,顧客需要創建各自的商店,再去購買。。。

      上面實體類不變,只需要添加一個門面類(外觀類)即可

      核心(外觀類):

      public class myFacade { /** * 創建門面類(外觀類) */ //這幾個變量也可以寫成單例,這里暫且不寫 private appleStore appleStore; private bananaStore bananaStore; private orangeStore orangeStore; public myFacade(){ //初始化對象 this.appleStore=new appleStore(); this.bananaStore=new bananaStore(); this.orangeStore=new orangeStore(); } /** * 精髓。。。 * 使用外觀模式的外觀類來歸納方法,把多個類的方法歸納到一個外觀類中 * @return */ //創建門面方法(外觀方法),購買水果 //買蘋果 public apple buyAppleByfacade(){ apple apple = appleStore.buyApple(); apple.setId(UUID.randomUUID().toString().replaceAll("-","")); return apple; } //買香蕉 public banana buyBananaByfacade(){ banana banana = bananaStore.buyBanana(); banana.setId(UUID.randomUUID().toString().replaceAll("-","")); return banana; } //買橙子 public orange buyOrangeByfacade(){ orange orange = orangeStore.buyOrange(); orange.setId(UUID.randomUUID().toString().replaceAll("-","")); return orange; } }

      public class client { public static void main(String[] args) { //創建已經歸納好方法的外觀類 myFacade myFacade = new myFacade(); //購買水果 apple apple = myFacade.buyAppleByfacade(); banana banana = myFacade.buyBananaByfacade(); orange orange = myFacade.buyOrangeByfacade(); System.out.println(apple); System.out.println(banana); System.out.println(orange); } }

      這時候我們不需要創建商店了,只需要創建外觀類調用買水果方法即可。

      外觀模式優點:假如水果有1000種,那么我們就要創建1000個對象,而使用外觀模式,只需要創建一個外觀類的對象即可,只需要1個對象。這樣對比起來就相當明顯了。。。。。。。。。。。。。。。。。。

      橋接模式

      使用橋接類和需要被橋接的接口進行橋接

      案例:假設我們需要一個接口,用來連接mysql或者Oracle

      public interface connection { public void connectDatasource(); }

      public class connection_mysql implements connection { /* 連接mysql數據源 */ @Override public void connectDatasource() { System.out.println("mysql數據源連接成功!!!"); } }

      public class connection_oracle implements connection { /* 連接Oracle數據源 */ @Override public void connectDatasource() { System.out.println("oracle數據源連接成功!!!"); } }

      傳統方式測試:

      public class client_chuantong { public static void main(String[] args) { //傳統方法調用接口方法 connection connection=new connection_mysql(); connection.connectDatasource(); connection connection1=new connection_oracle(); connection.connectDatasource(); } }

      橋的抽象類:

      public abstract class bridge { /** * 橋的抽象類 */ public abstract void connection(); }

      橋的實現類

      public class bridgeImpl extends bridge { /** * 核心 * 使用了橋接模式之后,我們只需要創建橋接 */ private connection connection; //給對象注入 public bridgeImpl(connection connection){ this.connection=connection; } //橋接方法(橋接接口方法) @Override public void connection() { connection.connectDatasource(); } }

      橋接測試:

      public class client_bridge { public static void main(String[] args) { //使用橋接實現類調用被橋接的接口方法 bridge bridge = new bridgeImpl(new connection_oracle()); bridge.connection(); } }

      觀察者模式

      既然有觀察者,那么也就有被觀察者。一個被觀察者被多個觀察者觀察。比如說天氣預報,天氣預報就是被觀察者,訂閱了天氣預報的人就是觀察者,天氣預報需要通知觀察者。

      被觀察者接口:

      public interface observerable { /** * 被觀察者 */ //添加觀察者 public void addObserver(observer observer); //移除觀察者 public void removeObserver(observer observer); //通知所有觀察者 public void notifyAllObserver(); }

      觀察者接口:

      public interface observer { /** * 觀察者 */ //接收通知的方法 public void getTianqi(tianqi tianqi); }

      被觀察者(在這是天氣預報):

      public class tianqi implements observerable { /** * 被觀察者 :天氣預報 */ private String date;//日期 private String wendu;//攝氏度 private List observers; //管理所有觀察者,以便通知觀察者們(其實也就是調用觀察者的接收通知方法) public tianqi(){ this.observers=new ArrayList<>(); this.date="2021/5/9"; this.wendu="37°C"; } public tianqi(String date, String wendu) { this.date=date; this.wendu=wendu; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getWendu() { return wendu; } public void setWendu(String wendu) { this.wendu = wendu; } @Override public void addObserver(observer observer) { observers.add(observer); } @Override public void removeObserver(observer observer) { observers.remove(observer); } @Override public void notifyAllObserver() { if(observers.size()>0){ for (int i = 0; i < observers.size(); i++) { observers.get(i).getTianqi(new tianqi(this.date,this.wendu)); } }else{ System.out.println("沒有人訂閱過天氣預報。。。"); } } @Override public String toString() { return "天氣信息{" + "date='" + date + '\'' + ", wendu='" + wendu + '\'' + '}'; } }

      觀察者:

      public class person implements observer { /** * 人:觀察者 */ private String name; //觀察者名字 public person(String name){ this.name=name; } @Override public void getTianqi(tianqi tianqi) { System.out.println("當前用戶名為:"+name+","+tianqi); } }

      客戶端(測試):

      public class client { public static void main(String[] args) { tianqi tianqi = new tianqi(); tianqi.addObserver(new person("小明")); tianqi.addObserver(new person("小華")); tianqi.notifyAllObserver(); System.out.println("=======修改后"); tianqi.addObserver(new person("小劉")); tianqi.setDate("2021/5/10"); tianqi.setWendu("15°C"); tianqi.notifyAllObserver(); } }

      備忘錄模式

      備忘錄模式:可以用來備份數據和恢復

      備忘錄需要有三個類:需要備份的類、originator(生成需要備份的類的對象),存儲數據和恢復數據的類

      責任鏈模式

      策略模式

      模板模式

      Java 網站

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:智聯世界—車聯網的應用和數字化未來發展(排放檢測篇)
      下一篇:【重大喜訊】六度共識云通過華為云鯤鵬生態兼容認證
      相關文章
      精品亚洲永久免费精品| 亚洲精品国产综合久久一线| 亚洲va无码va在线va天堂| 中文字幕精品亚洲无线码一区| 国产精品V亚洲精品V日韩精品| 亚洲av无码国产精品色在线看不卡| 人人狠狠综合久久亚洲| 亚洲国产精品精华液| 亚洲成在人线在线播放无码| 亚洲欧美一区二区三区日产| 亚洲精品乱码久久久久久V| 亚洲AV色欲色欲WWW| 国产成人高清亚洲一区久久| 亚洲成年人啊啊aa在线观看| 亚洲一级片免费看| 亚洲午夜久久久影院| 亚洲成a人片在线观看无码专区| 久久国产亚洲精品麻豆| 久久亚洲精品成人综合| 久久久久久亚洲AV无码专区| 亚洲精品中文字幕乱码影院| 亚洲av成人综合网| 亚洲日韩AV一区二区三区四区| 亚洲AV无码精品国产成人| 四虎亚洲国产成人久久精品| 亚洲熟伦熟女新五十路熟妇| 亚洲女同成av人片在线观看| 亚洲AV永久青草无码精品| 精品亚洲A∨无码一区二区三区| 亚洲国产av高清无码| 亚洲中文字幕一二三四区| 久久久久久亚洲精品无码| 亚洲日韩国产精品乱| 久久精品国产亚洲麻豆| 亚洲AV无码久久精品狠狠爱浪潮| 久久亚洲日韩看片无码| 亚洲午夜无码久久久久小说| 九月婷婷亚洲综合在线| 亚洲人成亚洲人成在线观看| 久久夜色精品国产噜噜噜亚洲AV| 亚洲av永久无码精品三区在线4 |