命令模式-接收者與執行者解耦和

来源:https://www.cnblogs.com/yangxiaojie/archive/2018/12/08/10088971.html
-Advertisement-
Play Games

將動作執行與接收者包裝到對象裡面,對外暴露的只有一個介面中的execute方法,其他對象不需要知道那個接收者執行了什麼動作,只需要知道調用execute,就能完成一個請求的操作 ...


老闆:阿飛,咱們公司又接了個新項目,一個客戶,,卧室和客廳很大,電燈電視開關也不好找,所以希望製造一個遙控器來控制一些傢具的開啟與關閉,目前需要5個按鍵,卧室的燈,卧室的電視,客廳的燈,客廳的電視,在留一個預備按鍵。我等會把需求文檔給你。
項目組長阿飛:好的,老闆
項目組長阿飛:小三,來了個需求,你看下,你先設計一下架構
阿三:好的,飛哥

三天過後:飛哥,好了,你看下

先設計了一個介面,裡面包含了,每一個按鈕的統一行為

 1 package com.commandPattern.command;
 2 
 3 /**
 4 * @program: testPattern
 5 * @description: 命令介面
 6 * @author: Mr.Yang
 7 * @create: 2018-12-08 13:54
 8 **/
 9 public interface Command {
10 
11 //執行方法
12 public void exceute();
13 
14 }
View Code

 


然後建立了一個對象,代表了空對象,什麼操作也不執行

 

package com.commandPattern.command.nullCommand;

import com.commandPattern.command.Command;

/**
* @program: testPattern
* @description: 建立一個空對象,在許多設計模式種,都會看到空對象的使用,甚至有些時候,空對象本身也被視為一種設計模式
* @author: Mr.Yang
* @create: 2018-12-08 17:40
**/
public class NullCommand implements Command {
public void exceute() {
System.out.println("什麼都不做處理");
}
}

 

燈的具體類

package com.commandPattern.entity;

/**
* @program: testPattern
* @description: 燈的具體類
* @author: Mr.Yang
* @create: 2018-12-08 17:31
**/
public class Lamp {
private String name;

/**
* name為燈的具體裝飾,即為哪裡的燈
* @param name
*/
public Lamp(String name){
this.name=name;
}
public void on (){
System.out.println(name+"_燈打開");
}
public void off (){
System.out.println(name+"_燈關閉");
}
}

 

電視的具體類

 

package com.commandPattern.entity;

/**
* @program: testPattern
* @description: 電視的具體類
* @author: Mr.Yang
* @create: 2018-12-08 17:35
**/
public class Tv {
private String name;
public Tv(String name){
this.name=name;
}
public void on (){
System.out.println(name+"_電視打開");
}
public void off(){
System.out.println(name+"_電視關閉");
}
}

 


關閉燈的具體命令

package com.commandPattern.command.off;

import com.commandPattern.command.Command;
import com.commandPattern.entity.Lamp;

/**
* @program: testPattern
* @description: 燈關閉
* @author: Mr.Yang
* @create: 2018-12-08 17:33
**/
public class LampOffCommand implements Command {

Lamp lamp;

public LampOffCommand(Lamp lamp){
this.lamp=lamp;
}
//燈關閉
public void exceute() {
lamp.off();
}
}

 

打開燈的具體命令

package com.commandPattern.command.on;

import com.commandPattern.command.Command;
import com.commandPattern.entity.Lamp;

/**
* @program: testPattern
* @description: 燈打開的命令
* @author: Mr.Yang
* @create: 2018-12-08 17:29
**/
public class LampOnCommand implements Command {

Lamp lamp;
public LampOnCommand(Lamp lamp){
this.lamp=lamp;
}

//燈打開的命令
public void exceute() {
lamp.on();
}
}

 

電視關閉的具體命令

package com.commandPattern.command.off;

import com.commandPattern.command.Command;
import com.commandPattern.entity.Tv;

/**
* @program: testPattern
* @description: 電視關閉
* @author: Mr.Yang
* @create: 2018-12-08 17:36
**/
public class TvOffCommand implements Command {
Tv tv;
public TvOffCommand(Tv tv){
this.tv=tv;
}
public void exceute() {
tv.off();
}
}

 

電視打開的具體命令

package com.commandPattern.command.on;

import com.commandPattern.command.Command;
import com.commandPattern.entity.Tv;

/**
* @program: testPattern
* @description: 電視打開
* @author: Mr.Yang
* @create: 2018-12-08 17:37
**/
public class TvOnCommand implements Command {
Tv tv;
public TvOnCommand(Tv tv){
this.tv=tv;
}

public void exceute() {
tv.on();
}
}

 

建立一個遙控器

package com.commandPattern.control;

import com.commandPattern.command.Command;
import com.commandPattern.command.nullCommand.NullCommand;

import java.util.Arrays;

/**
* @program: testPattern
* @description: 遙控器
* @author: Mr.Yang
* @create: 2018-12-08 17:39
**/
public class RemoteControl {

Command[] onCommand;
Command[] offCommand;

//初始化每個操作為空操作
public RemoteControl(){
onCommand=new Command[5];
offCommand=new Command[5];
NullCommand nullCommand = new NullCommand();
for (int i = 0; i < 5; i++) {
onCommand[i]=nullCommand;
offCommand[i]=nullCommand;
}
}

public void setCommond(int index,Command onCommand,Command offCommand){
this.offCommand[index]=offCommand;
this.onCommand[index]=onCommand;
}

public void clickOn(int index){
onCommand[index].exceute();
}

public void clickOff(int index){
offCommand[index].exceute();
}

/**
* 輸出每個按鈕的具體代表類
* @return
*/
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < onCommand.length; i++) {
sb.append("[index : "+i+"] ");
sb.append(onCommand[i].getClass().getName());
sb.append(" ");
sb.append(offCommand[i].getClass().getName());
sb.append("\r\n");
}
return sb.toString();
}
}

 


測試類

 1 package com.commandPattern.testPattern;
 2 
 3 import com.commandPattern.command.off.LampOffCommand;
 4 import com.commandPattern.command.off.TvOffCommand;
 5 import com.commandPattern.command.on.LampOnCommand;
 6 import com.commandPattern.command.on.TvOnCommand;
 7 import com.commandPattern.control.RemoteControl;
 8 import com.commandPattern.entity.Lamp;
 9 import com.commandPattern.entity.Tv;
10 
11 /**
12 * @program: test
13 * @description:
14 * @author: Mr.Yang
15 * @create: 2018-12-08 17:48
16 **/
17 public class TestPattern {
18 public static void main(String[] args) {
19 RemoteControl remoteControl = new RemoteControl();
20 
21 /**
22 * 創建裝置到合適位置
23 */
24 Tv bedRoomTV = new Tv("卧室");
25 Tv drawiTV = new Tv("客廳");
26 
27 Lamp bedRoomLamp = new Lamp("卧室");
28 Lamp drawiLamp = new Lamp("客廳");
29 
30 /**
31 * 創建所有命令操作對象
32 */
33 //卧室燈關閉對象
34 LampOffCommand bedLampOffCommand = new LampOffCommand(bedRoomLamp);
35 //卧室燈打開對象
36 LampOnCommand bedLampOnCommand = new LampOnCommand(bedRoomLamp);
37 //卧室TV關閉對象
38 TvOffCommand bedTvOffCommand = new TvOffCommand(bedRoomTV);
39 //卧室TV打開對象
40 TvOnCommand bedTVcommand = new TvOnCommand(bedRoomTV);
41 //客廳燈打開對象
42 LampOnCommand drawLampOnCommand = new LampOnCommand(drawiLamp);
43 //客廳燈關閉對象
44 LampOffCommand drawLampOffCommand = new LampOffCommand(drawiLamp);
45 //客廳TV關閉對象
46 TvOffCommand drawTVOffCommand = new TvOffCommand(drawiTV);
47 //客廳TV打開對象
48 TvOnCommand drawTVOnCommand = new TvOnCommand(drawiTV);
49 
50 System.out.println("---------------------------------------------未賦值之前------------------------------------------------");
51 System.out.println(remoteControl);
52 System.out.println("******************************************************************************************************");
53 
54 /**
55 * //將操作對象與卡槽一一對應
56 */
57 //賦值卧室燈打開與關閉
58 remoteControl.setCommond(0,bedLampOnCommand,bedLampOffCommand);
59 //賦值卧室TV打開與關閉
60 remoteControl.setCommond(1,bedTVcommand,bedTvOffCommand);
61 //賦值客廳燈打開與關閉
62 remoteControl.setCommond(2,drawLampOnCommand,drawLampOffCommand);
63 //賦值客廳TV打開與關閉
64 remoteControl.setCommond(3,drawTVOnCommand,drawTVOffCommand);
65 
66 System.out.println("---------------------------------------------賦值之後------------------------------------------------");
67 System.out.println(remoteControl);
68 System.out.println("******************************************************************************************************");
69 
70 
71 /**
72 * 測試每一個按鈕
73 */
74 remoteControl.clickOn(0);
75 remoteControl.clickOff(0);
76 
77 remoteControl.clickOn(1);
78 remoteControl.clickOff(1);
79 
80 remoteControl.clickOn(2);
81 remoteControl.clickOff(2);
82 
83 remoteControl.clickOn(3);
84 remoteControl.clickOff(3);
85 
86 
87 }
88 }
View Code

 

測試結果

---------------------------------------------未賦值之前------------------------------------------------
[index : 0] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand
[index : 1] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand
[index : 2] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand
[index : 3] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand
[index : 4] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand

******************************************************************************************************
---------------------------------------------賦值之後------------------------------------------------
[index : 0] com.commandPattern.command.on.LampOnCommand com.commandPattern.command.off.LampOffCommand
[index : 1] com.commandPattern.command.on.TvOnCommand com.commandPattern.command.off.TvOffCommand
[index : 2] com.commandPattern.command.on.LampOnCommand com.commandPattern.command.off.LampOffCommand
[index : 3] com.commandPattern.command.on.TvOnCommand com.commandPattern.command.off.TvOffCommand
[index : 4] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand

******************************************************************************************************
卧室_燈打開
卧室_燈關閉
卧室_電視打開
卧室_電視關閉
客廳_燈打開
客廳_燈關閉
客廳_電視打開
客廳_電視關閉
View Code

 

阿三:飛哥,我這裡使用的設計模式-命令模式,
將動作執行(LampOnCommand,TvOnCommand……)與接收者(Lamp,Tv)包裝到對象裡面,對外暴露的只有一個Command介面中的execute方法,其他對象不需要知道那個接收者執行了什麼動作,只需要知道調用execute,就能完成一個請求的操作,這個對象,與其他對象沒有關聯,完全解耦和,如果需要做新增,不需要修改原有代碼,拓展接收者類和動作執行類,就能實現功能。

項目組長阿飛:不錯,不錯,進步很大。
項目組長阿飛:第5個按鈕可能需要做一個恢覆上一步動作的效果,類似於CTRL+Z這個效果,你再改改把。
阿三:好的。
阿三:飛哥修改好了,你看下

命令介面新增撤銷方法

package com.commandPattern.command;

/**
* @program: testPattern
* @description: 命令介面
* @author: Mr.Yang
* @create: 2018-12-08 13:54
**/
public interface Command {

//執行方法
public void exceute();

//撤銷方法
public void revoke();

}

 

建立一個空對象,實現了撤銷方法

package com.commandPattern.command.nullCommand;

import com.commandPattern.command.Command;

/**
* @program: testPattern
* @description: 建立一個空對象,在許多設計模式種,都會看到空對象的使用,甚至有些時候,空對象本身也被視為一種設計模式
* @author: Mr.Yang
* @create: 2018-12-08 17:40
**/
public class NullCommand implements Command {
public void exceute() {
System.out.println("什麼都不做處理");
}

public void revoke() {
System.out.println("什麼都不做處理");
}
}

 

燈關閉實現了撤銷方法

package com.commandPattern.command.off;

import com.commandPattern.command.Command;
import com.commandPattern.entity.Lamp;

/**
* @program: testPattern
* @description: 燈關閉
* @author: Mr.Yang
* @create: 2018-12-08 17:33
**/
public class LampOffCommand implements Command {

Lamp lamp;

public LampOffCommand(Lamp lamp){
this.lamp=lamp;
}
//燈關閉
public void exceute() {
lamp.off();
}
//執行到這個具體實現類,代表上一步是燈關閉,撤銷操作即為燈打開
public void revoke() {
lamp.on();
}
}

 

燈打開實現了撤銷方法

package com.commandPattern.command.on;

import com.commandPattern.command.Command;
import com.commandPattern.entity.Lamp;

/**
* @program: testPattern
* @description: 燈打開的命令
* @author: Mr.Yang
* @create: 2018-12-08 17:29
**/
public class LampOnCommand implements Command {

Lamp lamp;
public LampOnCommand(Lamp lamp){
this.lamp=lamp;
}

//燈打開的命令
public void exceute() {
lamp.on();
}
//執行到這個具體實現類,代表上一步是燈打開,撤銷操作即為燈關閉
public void revoke() {
lamp.off();
}
}

 

電視關閉實現了撤銷方法

package com.commandPattern.command.off;

import com.commandPattern.command.Command;
import com.commandPattern.entity.Tv;

/**
* @program: testPattern
* @description: 電視關閉
* @author: Mr.Yang
* @create: 2018-12-08 17:36
**/
public class TvOffCommand implements Command {
Tv tv;
public TvOffCommand(Tv tv){
this.tv=tv;
}
public void exceute() {
tv.off();
}
//執行到這個具體實現類,代表上一步是電視關閉,撤銷操作即為電視打開
public void revoke() {
tv.on();
}
}

 

電視打開實現了撤銷方法

package com.commandPattern.command.on;

import com.commandPattern.command.Command;
import com.commandPattern.entity.Tv;

/**
* @program: testPattern
* @description: 電視打開
* @author: Mr.Yang
* @create: 2018-12-08 17:37
**/
public class TvOnCommand implements Command {
Tv tv;
public TvOnCommand(Tv tv){
this.tv=tv;
}

public void exceute() {
tv.on();
}
//執行到這個具體實現類,代表上一步是電視打開,撤銷操作即為電視關閉
public void revoke() {
tv.off();
}
}

 

遙控器類,新增變數記錄上一步操作

package com.commandPattern.control;

import com.commandPattern.command.Command;
import com.commandPattern.command.nullCommand.NullCommand;

import java.util.Arrays;

/**
 * @program: testPattern
 * @description: 遙控器
 * @author: Mr.Yang
 * @create: 2018-12-08 17:39
 **/
public class RemoteControl {

    Command[] onCommand;
    Command[] offCommand;
    //這個變數來記錄上一個命令
    Command upStepCommand;
    //初始化每個操作為空操作
    public RemoteControl(){
        onCommand=new Command[5];
        offCommand=new Command[5];
        NullCommand nullCommand = new NullCommand();
        for (int i = 0; i < 5; i++) {
            onCommand[i]=nullCommand;
            offCommand[i]=nullCommand;
        }
        upStepCommand=nullCommand;
    }

    public void setCommond(int index,Command onCommand,Command offCommand){
        this.offCommand[index]=offCommand;
        this.onCommand[index]=onCommand;
    }
    //新增upStepCommand記錄上一步命令
    public void clickOn(int index){
        onCommand[index].exceute();
        upStepCommand=onCommand[index];
    }
    //新增upStepCommand記錄上一步命令
    public void clickOff(int index){
        offCommand[index].exceute();
        upStepCommand=offCommand[index];
    }

    public void toUpStepClick(){
        System.out.println("---撤銷---");
        upStepCommand.revoke();
    }
    /**
     * 輸出每個按鈕的具體代表類
     * @return
     */
    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < onCommand.length; i++) {
            sb.append("[index : "+i+"]   ");
            sb.append(onCommand[i].getClass().getName());
            sb.append("    ");
            sb.append(offCommand[i].getClass().getName());
            sb.append("\r\n");
        }
        return sb.toString();
    }
}
View Code

 

測試類新增撤銷測試

package com.commandPattern.testPattern;

import com.commandPattern.command.off.LampOffCommand;
import com.commandPattern.command.off.TvOffCommand;
import com.commandPattern.command.on.LampOnCommand;
import com.commandPattern.command.on.TvOnCommand;
import com.commandPattern.control.RemoteControl;
import com.commandPattern.entity.Lamp;
import com.commandPattern.entity.Tv;

/**
 * @program: test
 * @description:
 * @author: Mr.Yang
 * @create: 2018-12-08 17:48
 **/
public class TestPattern {
    public static void main(String[] args) {
        RemoteControl remoteControl = new RemoteControl();

        /**
         * 創建裝置到合適位置
         */
        Tv bedRoomTV = new Tv("卧室");
        Tv drawiTV = new Tv("客廳");

        Lamp bedRoomLamp = new Lamp("卧室");
        Lamp drawiLamp = new Lamp("客廳");

        /**
         * 創建所有命令操作對象
         */
        //卧室燈關閉對象
        LampOffCommand bedLampOffCommand = new LampOffCommand(bedRoomLamp);
        //卧室燈打開對象
        LampOnCommand bedLampOnCommand = new LampOnCommand(bedRoomLamp);
        //卧室TV關閉對象
        TvOffCommand bedTvOffCommand = new TvOffCommand(bedRoomTV);
        //卧室TV打開對象
        TvOnCommand bedTVcommand = new TvOnCommand(bedRoomTV);
        //客廳燈打開對象
        LampOnCommand drawLampOnCommand = new LampOnCommand(drawiLamp);
        //客廳燈關閉對象
        LampOffCommand drawLampOffCommand = new LampOffCommand(drawiLamp);
        //客廳TV關閉對象
        TvOffCommand drawTVOffCommand = new TvOffCommand(drawiTV);
        //客廳TV打開對象
        TvOnCommand drawTVOnCommand = new TvOnCommand(drawiTV);

        System.out.println("---------------------------------------------未賦值之前------------------------------------------------");
        System.out.println(remoteControl);
        System.out.println("******************************************************************************************************");

        /**
         * //將操作對象與卡槽一一對應
         */
        //賦值卧室燈打開與關閉
        remoteControl.setCommond(0,bedLampOnCommand,bedLampOffCommand);
        //賦值卧室TV打開與關閉
        remoteControl.setCommond(1,bedTVcommand,bedTvOffCommand);
        //賦值客廳燈打開與關閉
        remoteControl.setCommond(2,drawLampOnCommand,drawLampOffCommand);
        //賦值客廳TV打開與關閉
        remoteControl.setCommond(3,drawTVOnCommand,drawTVOffCommand);

        System.out.println("---------------------------------------------賦值之後------------------------------------------------");
        System.out.println(remoteControl);
        System.out.println("******************************************************************************************************");


        /**
         * 測試每一個按鈕
         */
        remoteControl.clickOn(0);
        remoteControl.clickOff(0);

        //撤銷一次
        remoteControl.toUpStepClick();
        System.out.println("\r\n");

        //撤銷一次
        remoteControl.toUpStepClick();
        System.out.println("\r\n");

        remoteControl.clickOn(1);
        remoteControl.clickOff(1);

        //撤銷一次
        remoteControl.toUpStepClick();
        System.out.println("\r\n");

        remoteControl.clickOn(2);
        remoteControl.clickOff(2);

        //撤銷一次
        remoteControl.toUpStepClick();
        System.out.println("\r\n");

        remoteControl.clickOn(3);
        remoteControl.clickOff(3);

        //撤銷一次
        remoteControl.toUpStepClick();
        System.out.println("\r\n");

    }
}
View Code

 

修改之後的測試結果

---------------------------------------------未賦值之前------------------------------------------------
[index : 0] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand
[index : 1] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand
[index : 2] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand
[index : 3] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand
[index : 4] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand

******************************************************************************************************
---------------------------------------------賦值之後------------------------------------------------
[index : 0] com.commandPattern.command.on.LampOnCommand com.commandPattern.command.off.LampOffCommand
[index : 1] com.commandPattern.command.on.TvOnCommand com.commandPattern.command.off.TvOffCommand
[index : 2] com.commandPattern.command.on.LampOnCommand com.commandPattern.command.off.LampOffCommand
[index : 3] com.commandPattern.command.on.TvOnCommand com.commandPattern.command.off.TvOffCommand
[index : 4] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand

******************************************************************************************************
卧室_燈打開
卧室_燈關閉
---撤銷---
卧室_燈打開


---撤銷---
卧室_燈打開


卧室_電視打開
卧室_電視關閉
---撤銷---
卧室_電視打開


客廳_燈打開
客廳_燈關閉
---撤銷---
客廳_燈打開


客廳_電視打開
客廳_電視關閉
---撤銷---
客廳_電視打開
View Code

 

項目組長阿飛:不錯,不錯,以後給你漲工資。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Primer C++第五版 讀書筆記(一) (如有侵權請通知本人,將第一時間刪文) 1.1-2.2 章節 關於C++變數初始化: 初始化不是賦值,初始化的含義是創建變數時賦予其一個初始值,而賦值的含義是把對象的當前值擦除,以一個新值來替代. 定義一個名為a的int變數並初始化為0,有以下4種方法: ... ...
  • python安裝之後預設是使用國外的源,使用pip下載模塊網速不是很好,有時候下到一半還會斷開連接,非常不方便,最好配置國內的源。 Windows下: 在Windows配置源可參考下麵兩個博客: https://www.cnblogs.com/Devopser/p/6201292.html http ...
  • 對於表達式,分為“左結合”和“右結合” 左結合:對於沒有 = 號的,從左到右邊,當然要考慮優先順序。 右結合:對於有 = 號存在的情況,右邊的自成一體,然後賦值給左邊變數 優先順序: 邏輯運算符的優先順序: not > and > or a=1 b=2 c=2 not a or b + 2 == c (( ...
  • 迭代器:迭代器協議和可迭代協議,for 迴圈的運行邏輯,迭代器的好處 ...
  • Python基礎知識(26):常用內建模塊(Ⅱ) 1、hashlib Python的hashlib提供了常見的摘要演算法,如MD5,SHA1等 摘要演算法又稱哈希演算法、散列演算法。 (1)它通過一個函數,把任意長度的數據轉換為一個長度固定的數據串(通常用16進位的字元串表示) (2)摘要演算法就是通過摘要函 ...
  • 說明 以下這個類 可以修飾你的函數,讓你的函數或命令的輸出結果在控制台輸出的同時,還能存儲為你指定的文件 免去你是用寫日誌函數的必要 優點: 完全不需要修改代碼對函數或語句直接裝飾就行 直接修飾語句 修飾函數中的控制台輸出 以裝飾器的方式修飾輸出 結果 此內容為個人原創,轉載請註明出處:https: ...
  • 新聞 "ML.NET 0.8——Machine Learning for .NET" ".NET Core 3預覽 1以及開源Windows桌面框架" ".NET Core 2.2" "嘗試C 8.0" ".NET Framework 4.8早期可用編譯包3694" "WPF,WinForms和Wi ...
  • Python的3.0版本,常被稱為Python 3000,或簡稱Py3k。相對於Python的早期版本,這是一個較大的升級。為了不帶入過多的累贅,Python 3.0在設計的時候沒有考慮向下相容。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...