您现在的位置是:网站首页 > 区块链应用中的特殊模式需求文章详情
区块链应用中的特殊模式需求
陈川
【
JavaScript
】
26230人已围观
13731字
区块链应用中的特殊模式需求
区块链技术带来了去中心化、不可篡改和共识机制等特性,这些特性在传统Web应用中并不常见。JavaScript设计模式需要针对这些特性进行适配和扩展,以满足区块链应用的特殊需求。从智能合约交互到数据同步机制,区块链应用对前端架构提出了独特挑战。
观察者模式与事件监听
区块链的不可变性使得数据变更通知成为关键需求。观察者模式天然适合处理区块链事件订阅:
class BlockchainEventEmitter {
constructor() {
this.observers = [];
}
subscribe(fn) {
this.observers.push(fn);
}
unsubscribe(fn) {
this.observers = this.observers.filter(subscriber => subscriber !== fn);
}
notify(data) {
this.observers.forEach(observer => observer(data));
}
}
// 使用示例
const blockEmitter = new BlockchainEventEmitter();
blockEmitter.subscribe(block => {
console.log(`New block mined: ${block.number}`);
});
// 模拟新区块到达
setInterval(() => {
blockEmitter.notify({ number: Math.floor(Math.random() * 1000) });
}, 5000);
以太坊的Web3.js库实际上内置了类似机制:
const Web3 = require('web3');
const web3 = new Web3('wss://mainnet.infura.io/ws');
web3.eth.subscribe('newBlockHeaders', (error, blockHeader) => {
if (!error) {
console.log(blockHeader);
}
});
策略模式与多链适配
不同区块链网络(以太坊、Solana、Polygon等)需要不同的交互策略:
class BlockchainStrategy {
constructor(strategy) {
this.strategy = strategy;
}
setStrategy(strategy) {
this.strategy = strategy;
}
async sendTransaction(tx) {
return this.strategy.execute(tx);
}
}
class EthereumStrategy {
async execute(tx) {
// 使用web3.js发送交易
return window.ethereum.request({
method: 'eth_sendTransaction',
params: [tx]
});
}
}
class SolanaStrategy {
async execute(tx) {
// 使用@solana/web3.js发送交易
const connection = new Connection(clusterApiUrl('mainnet-beta'));
return connection.sendTransaction(tx);
}
}
// 使用示例
const strategy = new BlockchainStrategy(new EthereumStrategy());
await strategy.sendTransaction({ from: '0x...', to: '0x...', value: '0x...' });
// 动态切换链
strategy.setStrategy(new SolanaStrategy());
代理模式与钱包交互
区块链应用需要处理敏感操作,代理模式可以增加安全层:
class WalletProxy {
constructor(realWallet) {
this.realWallet = realWallet;
this.accessLog = [];
}
sendTransaction(tx) {
if (this.validateTx(tx)) {
this.logAccess(tx);
return this.realWallet.sendTransaction(tx);
}
throw new Error('Invalid transaction');
}
validateTx(tx) {
// 验证逻辑
return tx.value < 100; // 示例:限制最大转账金额
}
logAccess(tx) {
this.accessLog.push({
timestamp: new Date(),
operation: 'sendTransaction',
details: tx
});
}
}
// 使用MetaMask等真实钱包的代理
const walletProxy = new WalletProxy({
sendTransaction: (tx) => window.ethereum.request({
method: 'eth_sendTransaction',
params: [tx]
})
});
工厂模式与智能合约实例化
不同智能合约需要不同的初始化参数和交互方式:
class ContractFactory {
static createContract(network, contractAddress, abi) {
switch (network) {
case 'ethereum':
return new web3.eth.Contract(abi, contractAddress);
case 'solana':
return new solanaWeb3.Contract(
programId,
idl,
provider
);
default:
throw new Error('Unsupported network');
}
}
}
// 使用示例
const erc20Contract = ContractFactory.createContract(
'ethereum',
'0x...',
ERC20_ABI
);
状态模式与交易生命周期
区块链交易有明确的状态流转(pending/confirmed/failed):
class TransactionState {
constructor(context) {
this.context = context;
}
handle() {}
}
class PendingState extends TransactionState {
handle() {
console.log('Transaction pending...');
// 检查交易状态
setTimeout(() => {
if (Math.random() > 0.5) {
this.context.setState(new ConfirmedState(this.context));
} else {
this.context.setState(new FailedState(this.context));
}
}, 3000);
}
}
class ConfirmedState extends TransactionState {
handle() {
console.log('Transaction confirmed!');
this.context.complete();
}
}
class TransactionContext {
constructor() {
this.state = new PendingState(this);
this.completed = false;
}
setState(state) {
this.state = state;
this.state.handle();
}
complete() {
this.completed = true;
}
}
// 使用示例
const tx = new TransactionContext();
tx.state.handle(); // 开始状态处理
备忘录模式与交易回滚
区块链的不可变性使得错误恢复需要特殊处理:
class TransactionMemento {
constructor(state) {
this.state = JSON.parse(JSON.stringify(state));
this.timestamp = new Date();
}
}
class TransactionOriginator {
constructor() {
this.state = {};
}
save() {
return new TransactionMemento(this.state);
}
restore(memento) {
this.state = memento.state;
}
async executeOperations(operations) {
const snapshot = this.save();
try {
for (const op of operations) {
await op.execute();
this.state[op.id] = op.result;
}
} catch (error) {
console.error('Operation failed, rolling back...');
this.restore(snapshot);
throw error;
}
}
}
装饰器模式与Gas费估算
动态添加Gas费计算功能:
function withGasEstimation(target, property, descriptor) {
const originalMethod = descriptor.value;
descriptor.value = async function(...args) {
const tx = args[0];
const gasEstimate = await this.estimateGas(tx);
console.log(`Estimated gas: ${gasEstimate}`);
return originalMethod.apply(this, args);
};
return descriptor;
}
class TransactionService {
@withGasEstimation
async sendTransaction(tx) {
return window.ethereum.request({
method: 'eth_sendTransaction',
params: [tx]
});
}
async estimateGas(tx) {
return window.ethereum.request({
method: 'eth_estimateGas',
params: [tx]
});
}
}
组合模式与批量交易
处理多个原子操作的组合:
class BlockchainOperation {
execute() {}
}
class SimpleTransaction extends BlockchainOperation {
constructor(tx) {
super();
this.tx = tx;
}
async execute() {
return window.ethereum.request({
method: 'eth_sendTransaction',
params: [this.tx]
});
}
}
class BatchOperation extends BlockchainOperation {
constructor() {
super();
this.operations = [];
}
add(operation) {
this.operations.push(operation);
}
async execute() {
const results = [];
for (const op of this.operations) {
results.push(await op.execute());
}
return results;
}
}
// 使用示例
const batch = new BatchOperation();
batch.add(new SimpleTransaction({ from: '0x...', to: '0x...', value: '0x1' }));
batch.add(new SimpleTransaction({ from: '0x...', to: '0x...', value: '0x2' }));
await batch.execute();
适配器模式与跨链兼容
统一不同区块链的API接口:
class UniversalBlockchainAdapter {
constructor(provider) {
this.provider = provider;
}
async getBalance(address) {
if (this.provider.eth) {
// 以太坊风格
return this.provider.eth.getBalance(address);
} else if (this.provider.getBalance) {
// Solana风格
return this.provider.getBalance(address);
}
throw new Error('Unsupported provider');
}
}
// 使用示例
const ethAdapter = new UniversalBlockchainAdapter(web3);
const solAdapter = new UniversalBlockchainAdapter(solanaConnection);
const ethBalance = await ethAdapter.getBalance('0x...');
const solBalance = await solAdapter.getBalance('SolanaAddress...');
单例模式与全局Web3实例
确保Web3实例全局唯一:
class Web3Singleton {
static instance = null;
constructor() {
if (!Web3Singleton.instance) {
this.web3 = new Web3(window.ethereum);
Web3Singleton.instance = this;
}
return Web3Singleton.instance;
}
static getInstance() {
if (!Web3Singleton.instance) {
Web3Singleton.instance = new Web3Singleton();
}
return Web3Singleton.instance;
}
}
// 使用示例
const web3Instance1 = Web3Singleton.getInstance();
const web3Instance2 = Web3Singleton.getInstance();
console.log(web3Instance1 === web3Instance2); // true
命令模式与交易队列
处理交易排队和重试逻辑:
class TransactionCommand {
constructor(execute, undo, value) {
this.execute = execute;
this.undo = undo;
this.value = value;
}
}
class TransactionQueue {
constructor() {
this.history = [];
this.queue = [];
}
addToQueue(command) {
this.queue.push(command);
}
async processQueue() {
while (this.queue.length > 0) {
const command = this.queue.shift();
try {
await command.execute(command.value);
this.history.push(command);
} catch (error) {
console.error('Execution failed, attempting undo...');
await command.undo(command.value);
}
}
}
}
// 使用示例
const queue = new TransactionQueue();
const sendTxCommand = new TransactionCommand(
(tx) => window.ethereum.request({
method: 'eth_sendTransaction',
params: [tx]
}),
(tx) => console.log(`Reverting tx: ${tx}`)
);
queue.addToQueue(sendTxCommand);
queue.processQueue();
中介者模式与跨组件通信
协调钱包连接、网络切换等全局状态:
class BlockchainMediator {
constructor() {
this.components = {};
}
register(component) {
this.components[component.name] = component;
component.setMediator(this);
}
notify(sender, event, data) {
switch (event) {
case 'networkChanged':
this.handleNetworkChange(sender, data);
break;
case 'accountChanged':
this.handleAccountChange(sender, data);
break;
}
}
handleNetworkChange(sender, chainId) {
Object.values(this.components).forEach(component => {
if (component !== sender) {
component.networkUpdated(chainId);
}
});
}
}
class WalletComponent {
constructor() {
this.name = 'wallet';
this.mediator = null;
}
setMediator(mediator) {
this.mediator = mediator;
}
onNetworkChange(chainId) {
this.mediator.notify(this, 'networkChanged', chainId);
}
networkUpdated(chainId) {
console.log(`Wallet received network update: ${chainId}`);
}
}
访问者模式与区块链数据分析
处理不同区块链数据的解析:
class BlockchainDataVisitor {
visitTransaction(tx) {}
visitBlock(block) {}
}
class GasFeeAnalyzer extends BlockchainDataVisitor {
visitTransaction(tx) {
return {
gasUsed: tx.gasUsed,
gasPrice: tx.gasPrice,
fee: tx.gasUsed * tx.gasPrice
};
}
}
class BlockchainData {
accept(visitor) {}
}
class TransactionData extends BlockchainData {
constructor(tx) {
super();
this.tx = tx;
}
accept(visitor) {
return visitor.visitTransaction(this.tx);
}
}
// 使用示例
const tx = { gasUsed: 21000, gasPrice: 20000000000 };
const txData = new TransactionData(tx);
const analyzer = new GasFeeAnalyzer();
const result = txData.accept(analyzer);
console.log(`Transaction fee: ${result.fee} wei`);
享元模式与ABI缓存
优化智能合约ABI的存储:
class ABIFlyweightFactory {
constructor() {
this.abis = {};
}
getABI(contractName) {
if (!this.abis[contractName]) {
this.abis[contractName] = this.loadABI(contractName);
}
return this.abis[contractName];
}
loadABI(contractName) {
// 实际项目中从文件系统或网络加载
const abis = {
ERC20: [...],
Uniswap: [...]
};
return abis[contractName];
}
}
// 使用示例
const factory = new ABIFlyweightFactory();
const erc20ABI = factory.getABI('ERC20');
const uniswapABI = factory.getABI('Uniswap');
责任链模式与交易验证
构建交易验证管道:
class ValidationHandler {
constructor() {
this.nextHandler = null;
}
setNext(handler) {
this.nextHandler = handler;
return handler;
}
handle(tx) {
if (this.nextHandler) {
return this.nextHandler.handle(tx);
}
return true;
}
}
class BalanceCheckHandler extends ValidationHandler {
handle(tx) {
if (tx.value > getBalance(tx.from)) {
throw new Error('Insufficient balance');
}
return super.handle(tx);
}
}
class GasCheckHandler extends ValidationHandler {
handle(tx) {
if (tx.gas < 21000) {
throw new Error('Gas too low');
}
return super.handle(tx);
}
}
// 使用示例
const validator = new BalanceCheckHandler();
validator.setNext(new GasCheckHandler());
try {
validator.handle({
from: '0x...',
value: 100,
gas: 20000
});
} catch (error) {
console.error(error.message);
}
模板方法模式与交易流程
定义标准化的交易处理流程:
abstract class TransactionTemplate {
async executeTransaction() {
this.validate();
const nonce = await this.getNonce();
const tx = this.prepareTransaction(nonce);
const signedTx = await this.signTransaction(tx);
return this.sendTransaction(signedTx);
}
abstract validate();
abstract getNonce();
abstract prepareTransaction(nonce);
abstract signTransaction(tx);
abstract sendTransaction(signedTx);
}
class ERC20Transfer extends TransactionTemplate {
validate() {
if (!this.recipient) throw new Error('Recipient required');
}
async getNonce() {
return web3.eth.getTransactionCount(this.sender);
}
prepareTransaction(nonce) {
return {
from: this.sender,
to: this.tokenAddress,
data: this.encodeTransfer(),
nonce,
gas: 50000
};
}
}
桥接模式与多钱包支持
分离抽象和实现以支持不同钱包:
class WalletProvider {
connect() {}
signTransaction() {}
}
class MetaMaskProvider extends WalletProvider {
connect() {
return window.ethereum.request({ method: 'eth_requestAccounts' });
}
}
class WalletConnectProvider extends WalletProvider {
connect() {
// WalletConnect特定的实现
}
}
class WalletService {
constructor(provider) {
this.provider = provider;
}
async connect() {
return this.provider.connect();
}
async sign(tx) {
return this.provider.signTransaction(tx);
}
}
// 使用示例
const mmService = new WalletService(new MetaMaskProvider());
const wcService = new WalletService(new WalletConnectProvider());
上一篇: 量子计算对编程模式的影响
下一篇: 设计模式与元宇宙开发