2007-11-06 23:01:00 szjerrywangyong 阅读数 308
  • SCRUM敏捷开发视频教程

    SCRUM敏捷开发视频教程,该课程为你分享SCRUM敏捷开发,理解敏捷的本质,认识中国IT行业对敏捷的挑战,学会让敏捷落地的实用招数。 嘉宾介绍:张传波 1. 创新工场创业课程(敏捷课程)讲师 2.软件研发管理佳实践顾问(曾任华为某团队研发顾问) 3. 中国敏捷联盟《ADBOK》(敏捷开发知识体系)项目组成员 二十年软件开发、软件设计、需求分析、项目管理、部门管理、公司管理及过程改进等经验,亲历“无数”项目,涉猎建筑、通讯、互联网、电力、金融、制造业、政府等领域,熟悉软件生命周期的全部过程

    10433 人正在学习 去看看 CSDN讲师
http://www.itpub.net/868217.html
2016-09-09 18:44:58 u011790275 阅读数 2926
  • SCRUM敏捷开发视频教程

    SCRUM敏捷开发视频教程,该课程为你分享SCRUM敏捷开发,理解敏捷的本质,认识中国IT行业对敏捷的挑战,学会让敏捷落地的实用招数。 嘉宾介绍:张传波 1. 创新工场创业课程(敏捷课程)讲师 2.软件研发管理佳实践顾问(曾任华为某团队研发顾问) 3. 中国敏捷联盟《ADBOK》(敏捷开发知识体系)项目组成员 二十年软件开发、软件设计、需求分析、项目管理、部门管理、公司管理及过程改进等经验,亲历“无数”项目,涉猎建筑、通讯、互联网、电力、金融、制造业、政府等领域,熟悉软件生命周期的全部过程

    10433 人正在学习 去看看 CSDN讲师

2016.9.9,深圳  Ken Fang

我们真的已经找到了如何以敏捷开发的模式, 做好真正的微服务...

只是谈谈鸡汤,开开会,估估没人会真正开心的工作量,站起来拍拍手的敏捷,对任何团队、任何人是ㄧ点帮助都没有的。敏捷应该是(而且已经是证明的)要和软件工程无缝的结合的;使得团队能将市场、行销、研发高效的协作、自主的管理,共同的打造能适应变化、对外部的世界产生最大正面影响的产品 (产品架构)。

云服务化产品;微服务的产品架构,是这类型的产品能在市场上成功的关键。

团队在 Product Owner 的带领下,借由微服务产品级敏捷的工程实践,使得团队的架构师、开发人员、测试人员,可高效的协作,并共同的完成:

@ 特性的业务场景分析。

@ 特性架构对外的依赖分析。

@ 微服务边界上下文(粒度)的分析。

@ 微服务架构方案的选定。

@ 既有系统搬迁到微服务架构下的架构方案与执行计划。

@ Functional Services Infrastructure Services 之间协作机制的设计。

@ 微服务对外的 Rest 接口设计。

团队已在构建微服务的生态系统下,成功的迈开了第一步;今天,真是值得纪念的一天。

更期待团队能坚持的走下去;拉通市场与行销,使得产品能真正的做到…在最短的时间内,就能适应市场的变化并响应客户的诉求。

更期待团队能坚持的走下去,一步一脚印,实实在在的走向真正的微服务的顶峰。




SaveSaveSaveSaveSaveSaveSaveSave
2008-09-14 22:49:00 scrumcn 阅读数 670
  • SCRUM敏捷开发视频教程

    SCRUM敏捷开发视频教程,该课程为你分享SCRUM敏捷开发,理解敏捷的本质,认识中国IT行业对敏捷的挑战,学会让敏捷落地的实用招数。 嘉宾介绍:张传波 1. 创新工场创业课程(敏捷课程)讲师 2.软件研发管理佳实践顾问(曾任华为某团队研发顾问) 3. 中国敏捷联盟《ADBOK》(敏捷开发知识体系)项目组成员 二十年软件开发、软件设计、需求分析、项目管理、部门管理、公司管理及过程改进等经验,亲历“无数”项目,涉猎建筑、通讯、互联网、电力、金融、制造业、政府等领域,熟悉软件生命周期的全部过程

    10433 人正在学习 去看看 CSDN讲师

 

内容简介

在这本书中,享誉全球的软件开发专家和软件工程大师Robert C.Martin将向您展示如何解决软件开发人员、项目经理及软件项目领导们所面临的最棘手的问题。这本综合性、实用性的敏捷开发和极限编程方面的指南,是由敏捷开发的创始人之一所撰写的。
  ·讲述在预算和实践要求下,软件开发人员和项目经理如何使用敏捷开发完成项目。
  ·使用真实案例讲解如何用极限编程来设计、测试、重构和结对编程。
  ·包含了极具价值的可多次使用的C++和JAVA源代码
  ·重点讲述了如何使用UML和设计模式解决面向客户系统的问题

目录

第Ⅰ部分 敏捷开发
第一章 敏捷实践
第二章 极限编程概述
第三章 计划
第四章 测试
第五章 重构
第六章 一次编程实践

第Ⅱ部分 敏捷设计
第七章 什么是敏捷设计
第八章 单一责任原则(SRP)
第九章 开放—封闭原则(OCP)
第十章 Liskov替换原则(LSP)
第十一章 依赖倒置原则(DIP)
第十二章 接口隔离原则(ISP)

第Ⅲ部分 薪水支付案例研究

第十三章 COMMAND模式和ACTIVE OBJECT模式
第十四章 TEMPLATE METHOD模式和STRATEGY模式:继承与委托
第十五章 FACADE模式和MEDIATOR模式
第十六章 SINGLETON模式和MONOSTATE模式
第十七章 NULL OBJECT模式
第十八章 薪水支付案例研究:第一次迭代开始
第十九章 薪水支付案例研究:实现

第Ⅳ部分 打包薪水支付系统
第二十章 包的设计原则
第二十一章 FACTORY模式
第二十二章 薪水支付案例研究(第2部分)

第Ⅴ部分 气象站案例研究

第二十三章 COMPOSITE模式
第二十四章 OBSERVER模式——回归为模式
第二十五章 ABSTRACT SERVER模式、ADAPTER模式和BRIDGE模式
第二十六章 PROXY模式和STAIRWAY TO HEAVEN模式:管理第三方API
第二十七章 案例研究:气象站

第Ⅵ部分 ETS案例研究

第二十八章 VISITOR模式
第二十九章 STATE模式
第三十章 ETS框架

  下载

2012-04-16 20:56:23 gsfw2010 阅读数 380
  • SCRUM敏捷开发视频教程

    SCRUM敏捷开发视频教程,该课程为你分享SCRUM敏捷开发,理解敏捷的本质,认识中国IT行业对敏捷的挑战,学会让敏捷落地的实用招数。 嘉宾介绍:张传波 1. 创新工场创业课程(敏捷课程)讲师 2.软件研发管理佳实践顾问(曾任华为某团队研发顾问) 3. 中国敏捷联盟《ADBOK》(敏捷开发知识体系)项目组成员 二十年软件开发、软件设计、需求分析、项目管理、部门管理、公司管理及过程改进等经验,亲历“无数”项目,涉猎建筑、通讯、互联网、电力、金融、制造业、政府等领域,熟悉软件生命周期的全部过程

    10433 人正在学习 去看看 CSDN讲师

前段时间进许了设计模式的学习,收获挺多的。

接下来学习敏捷软件开发(原则、模式与实践),继续加强设计模式的学习,了解软件设计原则,并通过一个案例将

设计原则和设计模式运用到真实的项目当中去。

备注:

(1)参考书籍《敏捷软件开发--原则、模式与实践C#版》Bob大师所著

(2)博客中的设计和案例都来自于参考书籍,主要是为了加强理解和记忆。

奋斗奋斗奋斗

努力,努力,再努力!

2019-05-19 19:45:47 qq_36556651 阅读数 85
  • SCRUM敏捷开发视频教程

    SCRUM敏捷开发视频教程,该课程为你分享SCRUM敏捷开发,理解敏捷的本质,认识中国IT行业对敏捷的挑战,学会让敏捷落地的实用招数。 嘉宾介绍:张传波 1. 创新工场创业课程(敏捷课程)讲师 2.软件研发管理佳实践顾问(曾任华为某团队研发顾问) 3. 中国敏捷联盟《ADBOK》(敏捷开发知识体系)项目组成员 二十年软件开发、软件设计、需求分析、项目管理、部门管理、公司管理及过程改进等经验,亲历“无数”项目,涉猎建筑、通讯、互联网、电力、金融、制造业、政府等领域,熟悉软件生命周期的全部过程

    10433 人正在学习 去看看 CSDN讲师

员工薪水支付系统介绍

很早以前学习了敏捷软件开发:原则、模式与实践中的薪水支付案例,有些代码设计思想觉得特别好的,特来分享下。
本系统实现了一个计算员工薪水,并发放薪水的功能,该系统必须为不同类型的员工支付正确的薪水,员工类型和结构如下:

  • 有些员工是钟点工。会按照他们工作记录中每小时报酬字段的值对他们进行支付。他们每天会提交工作时间卡,其中记录了日期以及工作小时数。如果每天工作超过8小时,那么超过的部分会按照正常报酬的1.5倍进行支付。每周五对他们进行支付。
  • 有些员工完全以月薪进行支付。每个月的最后一个工作日对他们进行支付。在他们的雇员记录中有一个月薪字段。
  • 还有些销售员工,除了基本工资外,会根据他们的销售情况,支付他们一定数量的酬金。他们会提交销售凭条,其中记录了销售日期和数量。在他们的工作记录中有一个酬金字段,每隔一周的周五对他们进行支付。
    员工还可以自由选择发放薪水方式,可以选择银行卡发放、把支票保存在出纳人员那里随时支取或者通过邮寄方式发放。
    一些员工还会加入协会。每周需要扣除相应会费,协会有时也会针对单个协会成员征收服务费用。
    刚学Java的时候,学习视频里的讲师有提到写代码时要一个类一个方法只做一件事,遇到会变化的内容时要知道抽象出来,我觉得在这个系统里得到了充分的体现。
    有3种类型的员工,一般我们可以这么设计:

在这里插入图片描述
设计一个父类员工类,然后分别设计小时工、固定薪资员工、销售员工去继承父类员工类,但是这里有个问题,假如哪天有个需求说要把固定薪资员工转为小时工,或者把小时工转为销售员工时,我们该怎么办,很明显子类间是不能转化的。
解决方法是进行抽象,一些员工按小时支付,一些员工按固定薪资支付,一些员工按销售业绩支付。每种类型的员工都需要被支付,只是支付的策略不同,所以我们可以把支付的策略抽象出来。这就有了支付策略接口:

public interface PaymentClassification {//抽象出支付策略类

	double calculatePay(Paycheck payCheck);
}

员工类不用理会员工的支付形式,把支付形式交由支付策略接口去解决,由此的到三个实现类:
按工作小时支付:

/*
 * 小时工即按小时支付,把按小时支付计算单独拿出来实现
 */
public class HourlyClassification implements PaymentClassification {
	
	private double hourlyRate;//每小时工钱
	private List<TimeCard> timeCards=new ArrayList<TimeCard>();//记录员工的工作时间卡
	
	public HourlyClassification(double hourlyRate) {
		this.hourlyRate = hourlyRate;
	}

	public double calculatePay(Paycheck payCheck) {
		// TODO Auto-generated method stub
		double totalPay=0;
		for(TimeCard card:timeCards) {
			if(DateUtil.between(card.getDate(), payCheck.getPayPeriodStart(), payCheck.getPayPeriodend()))
				totalPay+=calculatePayForTimeCard(card);
		}
		return totalPay;
	}
	
	public void addTimeCard(TimeCard timeCard) {
		this.timeCards.add(timeCard);
	}
	
	public double calculatePayForTimeCard(TimeCard timeCard) {
		double hours=timeCard.getHours();
		if(hours>8) {
			return (8*hourlyRate+(hours-8)*hourlyRate*1.5);
		}else {
			return hours*hourlyRate;
		}
	}

	@Override
	public String toString() {
		return "HourlyClassification [hourlyRate=" + hourlyRate + ", timeCards=" + timeCards + "]";
	}

}

按固定薪资支付:

/*
 * 固定薪资支付
 */
public class SalariedClassification implements PaymentClassification {
	
	private double salary;
	
	public SalariedClassification(double salary) {
		this.salary=salary;
	}	

	public double calculatePay(Paycheck payCheck) {
		// TODO Auto-generated method stub
		return salary;
	}

	@Override
	public String toString() {
		return "SalariedClassification [salary=" + salary + "]";
	}
	
	

}

按销售情况支付:

/*
 * 销售员工薪资计算
 */
public class CommissionedClassification implements PaymentClassification {
	
	private double rate;//每笔销售单提成
	private double salary;//底薪
	private List<SalesReceipt> salesReceipt=new ArrayList<SalesReceipt>();
	
	public CommissionedClassification(double rate, double salary) {
		super();
		this.rate = rate;
		this.salary = salary;
	}

    public void addSalesReceipt(SalesReceipt sr) {
    	this.salesReceipt.add(sr);
    }

	public double calculatePay(Paycheck payCheck) {
		// TODO Auto-generated method stub
		double commission=0;
		for(SalesReceipt sr:salesReceipt) {
			if(DateUtil.between(sr.getDate(), payCheck.getPayPeriodStart(), payCheck.getPayPeriodend()))
				commission+=sr.getAmount()*rate;
		}
		return commission+salary;
	}

	@Override
	public String toString() {
		return "CommissionedClassification [rate=" + rate + ", salary=" + salary + ", salesReceipt=" + salesReceipt
				+ "]";
	}

}

支付策略已经抽象了,还有发放薪水的方式,继续抽象,把发放薪水的方式交由以下接口处理:

/*
 * 抽象支付薪资方式
 */
public interface PaymentMethod {

	void pay(Paycheck payCheck);
}

银行卡支付方式:

/*
 * 银行卡支付方式实现类
 */
public class BankMethod implements PaymentMethod {
	private String bank;//银行卡
	private double account;//应支付的工资
	
	public BankMethod(String bank, double account) {
		super();
		this.bank = bank;
		this.account = account;
	}

	public void pay(Paycheck payCheck) {
		// TODO Auto-generated method stub
        System.out.println("向银行卡"+bank+"支付"+payCheck.getNetPay()+"元钱");
	}

	@Override
	public String toString() {
		return "BankMethod [bank=" + bank + ", account=" + account + "]";
	}

}

到财务/出纳自取方式:

public class HoldMethod implements PaymentMethod {

	public void pay(Paycheck payCheck) {
		// TODO Auto-generated method stub
        System.out.println("到财务自取");
	}

	@Override
	public String toString() {
		return "HoldMethod [到财务自取]";
	}

}

邮寄方式:

/*
 * 邮寄支付工资方式实现类
 */
public class MailMethod implements PaymentMethod {
	
	private String address;
	public MailMethod(String address) {
		super();
		this.address = address;
	}


	public void pay(Paycheck payCheck) {
		// TODO Auto-generated method stub
        System.out.println("给"+address+"邮寄工资");
	}


	@Override
	public String toString() {
		return "MailMethod [address=" + address + "]";
	}

}

当我们继续理解需求,我们会发现小时工的薪水发放是每周五进行,固定薪资员工的薪水发放是每月月底,销售员工则是隔一周的周五,薪水的发放时间不一致,就需要对每种类型员工的发放时间进行单独计算,抽象出支付时间:

/*
 * 抽象出支付时间
 */
public interface PaymentSchedule {

	boolean isPayDate(LocalDate date);
	
	LocalDate getPayPeriodStartDate(LocalDate date);
}

该接口需实现两个方法,判断当前日子是否为支付日,返回上一次的支付日期。
每周周五进行支付:

/*
 * 按每周周五进行支付实现类
 */
public class WeeklySchedule implements PaymentSchedule {

	public boolean isPayDate(LocalDate date) {
		// TODO Auto-generated method stub
		return DateUtil.isFriday(date);
	}

	public LocalDate getPayPeriodStartDate(LocalDate date) {
		// TODO Auto-generated method stub
		return DateUtil.add(date, -6);
	}

	@Override
	public String toString() {
		return "WeeklySchedule [每周五支付]";
	}

}

月底支付:

/*
 * 按月进行支付
 */
public class MothlySchedule implements PaymentSchedule {

	public boolean isPayDate(LocalDate date) {
		// TODO Auto-generated method stub
		return DateUtil.isLastDayOfMonth(date);
	}

	public LocalDate getPayPeriodStartDate(LocalDate date) {
		// TODO Auto-generated method stub
		return DateUtil.getFirstDay(date);
	}

	@Override
	public String toString() {
		return "MothlySchedule [月底支付]";
	}

}

隔周周五支付:

/*
 * 隔周周五进行支付
 */
public class BiweeklySchedule implements PaymentSchedule {
	LocalDate firstPayableFriday = LocalDate.of(2019, 1, 4);

	public boolean isPayDate(LocalDate date) {
		// TODO Auto-generated method stub
		return DateUtil.isAfterFirday(date);
	}

	public LocalDate getPayPeriodStartDate(LocalDate date) {
		// TODO Auto-generated method stub
		return DateUtil.add(date, -13);
	}

	@Override
	public String toString() {
		return "BiweeklySchedule [隔周周五支付]";
	}

}

最后还有员工的会费计算,需要在计算薪资时扣除:

/*
 * 抽象会费计算,协会对象
 */
public interface Affiliation {

	double calculateDecutions(Paycheck paycheck);
}

这里实现了一个协会:

/*
 * 具体协会实现类,负责计算应扣除项
 */
public class UnionAffiliation implements Affiliation {

	private String memberId;
	private double weeklyBue;//每周固定应付款字段
	private List<ServiceChange> serviceChanges=new ArrayList<ServiceChange>();//不定时收的服务费
	public UnionAffiliation(String memberId, double weeklyBue) {
		super();
		this.memberId = memberId;
		this.weeklyBue = weeklyBue;
	}
	public String getMemberId() {
		return memberId;
	}
	public void setMemberId(String memberId) {
		this.memberId = memberId;
	}
	public double getWeeklyBue() {
		return weeklyBue;
	}
	public void setWeeklyBue(double weeklyBue) {
		this.weeklyBue = weeklyBue;
	}
	public void addServiceChanges(ServiceChange sc) {
		this.serviceChanges.add(sc);
	}
	public double calculateDecutions(Paycheck paycheck) {
		// TODO Auto-generated method stub
		int fridays=NumberOfFridaysInPayPeriod(paycheck.getPayPeriodStart(),paycheck.getPayPeriodend());
		double totalDue=fridays*weeklyBue;
		double totalChange=0;
		for(ServiceChange sc:serviceChanges) {
			if(DateUtil.between(sc.getDate(), paycheck.getPayPeriodStart(), paycheck.getPayPeriodend()))
				totalChange+=sc.getAmount();
		}
		return totalDue+totalChange;
	}
	private int NumberOfFridaysInPayPeriod(LocalDate start,
			LocalDate end) {
		ZonedDateTime zonedDatestart = start.atStartOfDay(ZoneId.systemDefault());
		ZonedDateTime zonedDateend = end.atStartOfDay(ZoneId.systemDefault());
		Date payPeriodStart=Date.from(zonedDatestart.toInstant());
		Date payPeriodEnd=Date.from(zonedDateend.toInstant());
		Calendar dayCa = Calendar.getInstance();
		dayCa.setTime(payPeriodStart);
		Calendar payPeriodEndCa = Calendar.getInstance();
		dayCa.setTime(payPeriodEnd);

		int fridays = 0;
		while (dayCa.before(payPeriodEndCa)) {
			if (dayCa.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY) {
				fridays++;
			}
			dayCa.add(Calendar.DATE, 1);
		}

		return fridays;
	}
	@Override
	public String toString() {
		return "UnionAffiliation [memberId=" + memberId + ", weeklyBue=" + weeklyBue + "]";
	}
	
}

OK,再回过头来看下员工类的实现,成员变量里对于会费的计算、薪资策略的计算、发放薪水方式、发放薪水时间计算都做了抽象,将发放薪水过程的各个方法都分给了不同的接口、类进行处理,类与类间做到了低耦合、高内聚的设计思路。

    private String id;
	private String name;
	private String address;
	private List<Affiliation> affiliations=new ArrayList<Affiliation>();
	
	private PaymentClassification classification;
	private PaymentMethod paymentMethod;
	private PaymentSchedule schedule;

在计算发放薪资时:

public void payDay(Paycheck pc) {//发放薪水
		double grossPay=classification.calculatePay(pc);//薪水计算交由支付策略类计算
		double deductions=calculateDeductions(pc);//应扣除项交由会费类处理
		double netPay=grossPay-deductions;
		pc.setDeductions(deductions);
		pc.setEmpId(id);
		pc.setGrossPay(grossPay);
		pc.setNetPay(netPay);
		paymentMethod.pay(pc);//薪资发放交由员工选择的发放形式处理
	}
	
	protected double calculateDeductions(Paycheck pc) {
		double deductions=0;
		for(Affiliation affiliation:affiliations) {
			deductions+=affiliation.calculateDecutions(pc);
		}
		return deductions;
	}

整个过程类与类间的分工明确,这里还有将发放的薪资进行了封装:

public class Paycheck {//封装应支付薪水类

	private LocalDate payPeriodStart;//薪水起始计算时间
	private LocalDate payPeriodend;//薪水结束计算时间
	private double grossPay;//应付
	private double deductions;//扣除
	private double netPay;//实付
	private String empId;
	
	
	public Paycheck(LocalDate payperiodStart,LocalDate payPeriodend) {
		this.payPeriodStart=payperiodStart;
		this.payPeriodend=payPeriodend;
	}


}

``

总结下,有人说薪水支付案例是最好的面向对象设计案例,通过这个案例的学习可以了解什么是面向接口编程而不是面向实现编程,如何设计把合适的功能分给合适的类去实现,个人觉得这个是策略设计模式非常好的运用,把代码逻辑封装到具有共同接口的独立的类中。
最后贴个自己写的本项目Github地址:

本项目Github地址

没有更多推荐了,返回首页