首页 > 其他分享 >代码大全中保持松散耦合的demo

代码大全中保持松散耦合的demo

时间:2024-07-27 17:40:57浏览次数:11  
标签:LookupVacationBenefit demo level days employee job time 耦合 大全

Q:

假设你有一段子程序,通过输入雇用日期和工作级别来查询员工每年获得的休假数量。这段子程序被命名为LookupVacationBenefit()。假设在另一个模块里已经有了一个employee对象,其中包含了雇用日期和工作级别,以及其他一些信息,该模块把这种对象传给LookupVacationBenefit()。
按照其他耦合标准,这两个模块间的耦合关系看上去是很松散的。这两个模块之间的employee连接是可见的,而且这里只存在一个连接。现在假设你需要在第三个模块中使用 LookupVacationBenefit(),这一模块中没有 employee 对象,但却包含雇用日期和工作级别。这样,LookupVacationBenefit()一下子就变得不太友好了,它无法和新的模块协同工作。
要使第三个模块能使用LookupVacationBenefit(),它就必须了解Employee类。它可能去临时拼凑一个只包含两个字段的employee 对象,但是这就需要了解 LookupvacationBenefit()的内部机制,也就是说,只有这两个字段才是 LookupvacationBenefit()所需的。这样的解决方案非常牵强,而且也十分丑陋。第二种解决方案可能是对 LookupVacationBenefit()做出修改,使它以雇用日期和工作级别作为参数,而不用employee。无论怎样,原有的那个模块与过去相比都已经变得更不灵活了。
从这个故事得到的好消息是,可以让一个不友好的模块变友好,只要把它变得更灵活--在这个例子里,这件事是通过明确以雇用日期和工作级别取代employee作为参数来实现的。 

 

A:

在软件设计中,保持模块间的低耦合和高内聚是提高代码可维护性和可扩展性的关键。针对你描述的情况,以下是一些改进 LookupVacationBenefit() 函数的建议,使其更加灵活和友好:

1. 重构函数参数

LookupVacationBenefit() 函数的参数从 employee 对象更改为所需的具体字段(即雇用日期和工作级别)。这样可以减少函数对 employee 对象的依赖,使其更易于在不同的模块中重用。

def LookupVacationBenefit(hire_date, job_level):
    # 计算休假数量的逻辑
    vacation_days = calculate_vacation_days(hire_date, job_level)
    return vacation_days

  

package main

import (
	"fmt"
	"time"
)

// Employee 结构体包含员工信息
type Employee struct {
	HireDate  time.Time
	JobLevel  string
}

// LookupVacationBenefit 根据员工的雇佣日期和工作级别查找休假天数
func LookupVacationBenefit(employee Employee) int {
	// 示例计算逻辑:根据工作年限和工作级别计算休假天数
	yearsOfService := time.Since(employee.HireDate).Hours() / (24 * 365)
	vacationDays := int(yearsOfService * 2) // 假设每年2天休假
	if employee.JobLevel == "Senior" {
		vacationDays += 5 // 高级员工额外5天
	}
	return vacationDays
}

func main() {
	employee := Employee{
		HireDate:  time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
		JobLevel:  "Senior",
	}

	days := LookupVacationBenefit(employee)
	fmt.Printf("Employee has %d vacation days\n", days)
}

  

package main

import (
	"fmt"
	"time"
)

// LookupVacationBenefit 根据雇佣日期和工作级别查找休假天数
func LookupVacationBenefit(hireDate time.Time, jobLevel string) int {
	yearsOfService := time.Since(hireDate).Hours() / (24 * 365)
	vacationDays := int(yearsOfService * 2)
	if jobLevel == "Senior" {
		vacationDays += 5
	}
	return vacationDays
}

func main() {
	hireDate := time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)
	jobLevel := "Senior"

	days := LookupVacationBenefit(hireDate, jobLevel)
	fmt.Printf("Employee has %d vacation days\n", days)
}

  

2. 使用依赖注入

通过依赖注入(Dependency Injection, DI),可以将所需的依赖(如 employee 对象)传递给函数或类,而不是让函数或类自己查找这些依赖。这有助于降低模块间的耦合度。

class VacationService:
    def __init__(self, employee):
        self.employee = employee

    def get_vacation_days(self):
        return LookupVacationBenefit(self.employee.hire_date, self.employee.job_level)

def LookupVacationBenefit(hire_date, job_level):
    # 计算休假数量的逻辑
    vacation_days = calculate_vacation_days(hire_date, job_level)
    return vacation_days

  

package main

import (
	"fmt"
	"time"
)

type Employee interface {
	GetHireDate() time.Time
	GetJobLevel() string
}

type ConcreteEmployee struct {
	HireDate  time.Time
	JobLevel  string
}

func (e *ConcreteEmployee) GetHireDate() time.Time {
	return e.HireDate
}

func (e *ConcreteEmployee) GetJobLevel() string {
	return e.JobLevel
}

func LookupVacationBenefit(employee Employee) int {
	yearsOfService := time.Since(employee.GetHireDate()).Hours() / (24 * 365)
	vacationDays := int(yearsOfService * 2)
	if employee.GetJobLevel() == "Senior" {
		vacationDays += 5
	}
	return vacationDays
}

func main() {
	employee := &ConcreteEmployee{
		HireDate:  time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
		JobLevel:  "Senior",
	}

	days := LookupVacationBenefit(employee)
	fmt.Printf("Employee has %d vacation days\n", days)
}

  

3. 封装 employee 对象

如果 employee 对象包含多个字段,但只有少数字段需要被 LookupVacationBenefit() 函数使用,可以考虑创建一个更小的封装对象或数据传输对象(Data Transfer Object, DTO),只包含必要的字段。

class EmployeeInfo:
    def __init__(self, hire_date, job_level):
        self.hire_date = hire_date
        self.job_level = job_level

def LookupVacationBenefit(employee_info):
    return calculate_vacation_days(employee_info.hire_date, employee_info.job_level)

  

4. 使用接口或抽象类

定义一个接口或抽象类来规范 employee 对象的行为,确保所有实现该接口的类都提供必要的方法和属性。这样可以在不修改 LookupVacationBenefit() 函数的情况下,使用不同类型的 employee 对象。

from abc import ABC, abstractmethod

class Employee(ABC):
    @abstractmethod
    def get_hire_date(self):
        pass

    @abstractmethod
    def get_job_level(self):
        pass

def LookupVacationBenefit(employee):
    return calculate_vacation_days(employee.get_hire_date(), employee.get_job_level())

  

5. 考虑使用工厂模式

如果 employee 对象的创建过程复杂,可以考虑使用工厂模式来封装对象的创建过程。这样,LookupVacationBenefit() 函数只需要关心如何使用 employee 对象,而不需要关心其创建过程。

class EmployeeFactory:
    @staticmethod
    def create_employee(hire_date, job_level):
        return Employee(hire_date, job_level)

def LookupVacationBenefit(hire_date, job_level):
    employee = EmployeeFactory.create_employee(hire_date, job_level)
    return calculate_vacation_days(employee.hire_date, employee.job_level)

  

通过这些方法,可以使 LookupVacationBenefit() 函数更加灵活,易于在不同的模块中重用,同时降低模块间的耦合度。

 

 

 

 

 

标签:LookupVacationBenefit,demo,level,days,employee,job,time,耦合,大全
From: https://www.cnblogs.com/gongxianjin/p/18327261

相关文章

  • rust wasm sycamore demo
    Cargo.toml:[package]name="wasmdemo"version="0.1.0"edition="2021"[dependencies]sycamore="0.9.0-beta.2"src/main.rs:usesycamore::prelude::*;#[component]fnApp<G:Html>()->View<G>......
  • 病毒大全
    分享一下我的病毒以下所有病毒禁止非(bu)法(shi)使用,否则后果自负!!!1.bat病毒最危险的病毒(保存为666.bat)后果:开机就关机解决办法:重装系统点击查看代码Copy666.bat“%userprofile%\AppData\Roaming\Microsoft\Windows\StartMenu\Programs\Startup\”taskkill/f/f......
  • Python 教程(三):字符串特性大全
    目录专栏列表前言1.字符串基础2.字符串方法字符串查询字符串修改字符串切片3.字符串格式化旧式格式化(`%`操作符)`str.format()`方法f-string(Python3.6+)4.字符串编码5.Unicode和ASCII6.正则表达式7.字符串比较8.字符串连接9.字符串不可变性10.字符串的内......
  • 8G 显存玩转书生大模型 Demo-任务一
    使用LMDeploy完成InternLM2-Chat-1.8B模型的部署,并生成300字小故事,记录复现过程并截图。详细步骤1.编写python文件2.执行(下载模型并运行)3.已命令行交互式运行4.生成300字小故事......
  • (三)复习第三课(07.20- 07.25第二轮):HTML标签元素练习大全
    <!DOCTYPEhtml><!--练习时间:2024.07.20-2024.07.25--><htmllang="en"><!--添加了en可以让你的网站打开时会提示翻译--><head> <pid="head1"></p><metacharset="utf-8"><!--对于中文网页需要使用此标签声明编码,否则会出现......
  • python cobs协议编解码算法demo
    1.SummaryCOBS(ConsistentOverheadByteStuffing)是一种算法,直译为一致的开销字节填充。简而言之,无论数据包的内容如何,都能通过产生高效可靠明确的数据包帧,从而使接受端能够从损坏的包中恢复。通常使用0x00来作为数据包的分隔符,即切割数据包的片分隔符。当使用0x00作为......
  • 【微信小程序开发】从0-1注册、下载、安装、开发保姆篇教程(附Demo源码)
    文章目录前期准备注册登陆下载安装创建项目项目结构版本管理程序页面生命周期新增页面功能实现本篇小结更多相关内容可查看前期准备要有前端开发基础,已安装NodeJS,若未安装请参考NodeJS安装并生成Vue脚手架(保姆级)可参考小程序开发官方文档进行学习,本文也是参考......
  • Maven中GeoTools的引入及Maven中央仓库地址大全
    Maven官方https://mvnrepository.com/repos/centralMaven中央仓库地址大全https://blog.csdn.net/chinawangfei/article/details/122049810Maven中GeoTools的引入-Maven的repository与mirrorhttps://blog.csdn.net/Sky_Tree_Delivery/article/details/105415048pom.xm......
  • webpack入门最简单的demo
    1、在空文件夹下npminit-y2、npminstall--save-devwebpack3、新建src文件夹,在src里新建index.html,写入:<!DOCTYPEhtml><htmllang="en"><head><metacharset="utf-8"><title>WebpackDemo</title></hea......
  • 跨境电商必学外贸用语大全
    跨境电商是一个涉及全球交易的复杂领域,它不仅包括在线销售和营销策略,还涵盖了国际贸易的物流和金融操作。了解和掌握跨境电商的专业术语,对于参与这一行业的企业和个人至关重要。本文将全面介绍跨境电商中的关键术语,包括电商模式、广告推广、店铺运营以及国际贸易中的物流和金融术......