🧑‍🏫
liualexiang
  • Introduction
  • Azure
    • AKS Basic
    • AKS Spark
    • AZ ACR SYNC
    • Azure CMI SDWAN
    • Azure LB DeepDive
      • Azure LB DeepDive
    • Azure Service Principal Basic
    • Azure Internal VM Network Connectivity
      • Azure Internal VM Network Connectivity
    • Azure Cli Build
    • Azure Vm Memory Monitor
  • Blockchain
    • BTC
  • CRISPR
    • 使用Parallel_Cluster提升CRISPA效率
  • OpenSource
    • ElasticSearch
      • ES Get Started
      • ES Search Query
      • Kibana 可视化
      • Logstash配置
    • Ansible 基础
    • Infra As Code
      • Pulumi Get Started
      • Terraform Basic
    • ZooKeeper 基础
    • RPC与REST
    • 使用Python申请大量内存测试
    • 使用TPC_DS产生压测数据
    • Superset
      • Superset部署手册
    • 代码扫描
    • Git
      • Git Basic
      • Github Action Basic
      • Gitlab与AzureAD集成
      • Gitbook 基础教程
    • K8S
      • enter_node
      • K8s X509 Client Cert
      • K8s Basic
      • K8s Oidc
      • Docker 基础
      • helm基础
      • K8S_Secrets管理
      • 深入了解K8S
      • 混沌工程
      • Istio
      • 生态
      • CRD开发
      • k8s网络
    • Cloud_Custodian
    • Jenkins Basic
    • Nginx
    • ETCD
    • 正则
    • VictoriaMetrics
    • Kafka
  • MySQL
    • MySQL 调优
  • Linux
    • SSH Tunnel 上网
    • 内存管理
    • 在Linux系统中通过LUKS加密磁盘
    • 量子计算 Basic
    • IO多路复用
    • Iptables
    • tmux和screen
    • Systemd
    • OS 基础
    • jq基础
    • yum
    • neovim
  • Web
    • Html Css
    • Web部署
    • 缓存
  • Programming
    • 算法
      • 返回list中最大生序子序列长度
    • Python技巧
      • Python的语法糖
      • Python常用装饰器
      • AsyncIO基础
      • 自动化测试pytest
      • python中的下划线
      • 面向对象
      • Python的坑
      • Python配置文件管理
      • HTTP Stream Response
      • Python项目管理
    • 设计模式
      • 设计模式
      • 面向对象的思想
      • 编程概念
    • Go
      • Go 基础
      • Go常用功能
      • 结构体入门
    • 前端
    • Vue
    • NodeJS
  • Math
    • 多项式插值法
  • Security
    • HTTP常见攻击
    • 加密与签名
    • RSA
    • ECDSA
  • Solidity
    • Solidity基础
    • Blockchain Testnet Faucet
  • Tools
    • 视频处理ffmpeg
    • IDE配置
    • iTerm2美化
    • 密码管理
    • FRP配置
    • 工具集
由 GitBook 提供支持
在本页
  1. Programming
  2. 设计模式

编程概念

  • closure 闭包:一个子函数,引用父函数的变量,当父函数执行完成,子函数依然能访问这些变量。

  • argument drilling: 指的是在开发的时候,函数在调用链的时候,有很多参数要传递,比如A调用B,传了一些参数,B调用C的时候,又要传这个参数。有几个办法可以解决这个问题

    • 对象传参:将相关参数封装到一个对象里

    • 依赖注入:用依赖注入来管理和传递函数所需要的依赖项

    • 使用全局变量虽然也能解决,但可能会引入其他问题,比如命名冲突,可维护性差,难以测试等,不推荐使用。

    • 使用 closure 闭包在一定程度上也能解决参数的问题,一个示例如下

      • 比如一个计算折扣的程序,原始写法如下

async function getUserDiscounts() {
    return {
        P001: 5,
        P002: 10
    }
}

async function getCategoryDiscounts() {
    return {
        electronics: 15,
        clothing: 5
    }
}

function proceeProducts(products, userDiscounts, categoryDiscounts) {
    return products
    .map((product) => {
        const userDiscount = userDiscounts[product.id] || 0;
        const categoryDiscount = categoryDiscounts[product.category] || 0;
        const totalDiscount = userDiscount + categoryDiscount;
        const finalPrice = product.price - product.price * (totalDiscount / 100);
        return {
            ...product, 
            finalPrice: finalPrice.toFixed(2)
        };
    })
    .filter((product) => product.finalPrice <= 80)
    .map((product) => product.id)
}

async function main() {
    const products = [
        {id: "P001", category: "electronics", price: 100},
        {id: "P002", category: "clothing", price: 50},
        {id: "P003", category: "electronics", price: 100},
        {id: "P004", category: "clothing", price: 80}
    ]
    const userDiscounts = await getUserDiscounts();
    const categoryDiscounts = await getCategoryDiscounts();

    const processedProducts = proceeProducts(
        products,
        userDiscounts,
        categoryDiscounts
    );

    console.log(
        processedProducts.reduce(
            (obj, key) => {obj[key] = key; return obj;}, {}
        )
    );
}

main()

此时折扣的逻辑在多个地方都会用到,此时我们可以创建一个createDiscountCalculator的函数专门计算折扣,这个函数需要接收 userDiscounts 和 categoryDiscounts 作为输入,在专门处理某一个商品时,然后再通过这个 discountCalculator 查一下商品折扣,具体改法是:

async function getUserDiscounts() {
    return {
        P001: 5,
        P002: 10
    }
}

async function getCategoryDiscounts() {
    return {
        electronics: 15,
        clothing: 5
    }
}

function createDiscountCalculator(userDiscounts, categoryDiscounts) {
    return function (product){
    const userDiscount = userDiscounts[product.id] || 0;
    const categoryDiscount = categoryDiscounts[product.category] || 0;
    const totalDiscount = userDiscount + categoryDiscount;
    const finalPrice = product.price - product.price * (totalDiscount / 100);

    return  finalPrice.toFixed(2);
    } 
}

function proceeProducts(products, discountCalculator) {
    return products
    .map((product) => {
        const finalPrice = discountCalculator(product);
        return {
            ...product, 
            finalPrice: finalPrice
        };
    })
    .filter((product) => product.finalPrice <= 80)
    .map((product) => product.id)
}

async function main() {
    const products = [
        {id: "P001", category: "electronics", price: 100},
        {id: "P002", category: "clothing", price: 50},
        {id: "P003", category: "electronics", price: 100},
        {id: "P004", category: "clothing", price: 80}
    ]
    const userDiscounts = await getUserDiscounts();
    const categoryDiscounts = await getCategoryDiscounts();
    const discountCalculator = createDiscountCalculator(
        userDiscounts,
        categoryDiscounts
    );

    const processedProducts = proceeProducts(
        products,
        discountCalculator
    );

    console.log(
        processedProducts
    );

    console.log(
        processedProducts.reduce(
            (obj, key) => {obj[key] = key; return obj;}, {}
        )
    );
}

main()

下面是一个python 通过闭包的一个实现

from decimal import Decimal, getcontext  
def user_discount():  
    return {  
        "P001": 5,  
        "P002": 10  
    }  
  
  
def category_discount():  
    return {  
        "electronics": 15,  
        "clothing": 5  
    }  
  
  
def discount_calculator(user_discount, category_discount):  
    def discount(product):  
        user_discount_percentage = user_discount.get(product["id"], 0)  
        category_discount_percentage = category_discount.get(product["category"], 0)  
        discount_percentage = user_discount_percentage + category_discount_percentage  
        discount_amount = product["price"] * Decimal(discount_percentage / 100)  
        discounted_price = product["price"] - discount_amount  
        return discounted_price  
    return discount  
  
  
def proceed_products(products, discount_calculator):  
    discounted_product = [{**product, 'finalPrice': discount_calculator(product)} for product in products]  
  
    filtered_products = [  
        product["id"] for product in discounted_product if product['finalPrice'] < 80  
    ]  
    return filtered_products  
  
if __name__ == '__main__':  
    products = [  
        {  
            "id": "P001",  
            "category": "electronics",  
            "price": 100  
        },  
        {  
            "id": "P002",  
            "category": "clothing",  
            "price": 50  
        },  
        {  
            "id": "P003",  
            "category": "electronics",  
            "price": 100  
        },  
        {  
            "id": "P004",  
            "category": "clothing",  
            "price": 80  
        }  
    ]  
    user_discount = user_discount()  
    category_discount = category_discount()  
    discount_calculator = discount_calculator(user_discount, category_discount)  
    discount_products = proceed_products(products, discount_calculator)  
    print(discount_products)
上一页面向对象的思想下一页Go

最后更新于11个月前