跨战区PK
创建类模式描述如何创建对象,行为类模式关注如何管理对象的行为,结构类模式则着重于如何建立一个软件结构。
1.策略模式 VS 桥梁模式
桥梁模式关注的是抽象和实现的分离。
策略模式是使用继承和多态建立一套可以自由切换算法的模式,桥梁模式是在不破坏封装的前提下解决抽象和实现都可以独立扩展的模式。
桥梁模式必然有两个“桥墩”——抽象化角色和实现化角色,而策略模式只有一个抽象角色,可以没有实现,也可以有很多实现。
桥梁模式实现邮件发送
//邮件模板
public abstract class MailTemplate{
//邮件发送人
private String from;
//收件人
private String to;
//邮件标题
private String subject;
//邮件内容
public String context;
//JavaBean规范...
//允许增加邮件发送标志
public void add(String sendInfo){
context = sendInfo + context;
}
}
//文本文件
public class TextMail extends MailTemplate {
public TextMail(String from,String to,String subject,String context){
super(from,to,subject,context);
}
public String getContext() {
//文本类型设置邮件的格式为:text/plain
String context = "\nContent-Type:text/plain;charset=GB2312\n"+super.getContext();
//同时对邮件进行base64编码处理,这里用一句话代替
context = context + "\n邮件格式为:文本格式";
return context;
}
}
//超文本文件
class HtmlMail extends MailTemplate {
public HtmlMail(String from,String to,String subject,String context){
super(from,to,subject,context);
}
public String getContext() {
//文本类型设置邮件的格式为:text/plain
String context = "\nContent-Type:multipart/mixed;charset=GB2312\n"+super.getContext();
//同时对邮件进行base64编码处理,这里用一句话代替
context = context + "\n邮件格式为:超文本格式";
return context;
}
}
//邮件服务器
abstract class MailServer{
//发送的是哪封邮件
protected final MailTemplate m;
public MailServer(MailTemplate m) {
this.m = m;
}
//发送文件
public void sendMail() {
//发件人
System.out.println("发件人:"+m.getFrom());
//收件人
System.out.println("收件人:"+m.getTo());
//标题
System.out.println("标题:"+m.getSubject());
//邮件内容
System.out.println("邮件内容:"+m.getContext());
}
}
//Postfix邮件服务器
class Postfix extends MailServer{
public Postfix(MailTemplate m) {
super(m);
}
//修改邮件发送程序
public void sendMail() {
//增加邮件服务器信息DBCD
String context = "Received:from xxx (unknown [xxx.xxx.xxx.xxx]) "
+ "by aaa.aaa.com (Postfix) with ESMTP id 8DBCD172B8\n";
super.m.add(context);
super.sendMail();
}
}
//SendMail邮件服务器
class SendMail extends MailServer{
public SendMail(MailTemplate m) {
super(m);
}
//修改邮件发送程序
public void sendMail() {
//增加邮件服务器信息DBCD
String context = "Received:(sendmail);7 Nov 2009 04:14:44 +0100\n";
super.m.add(context);
super.sendMail();
}
}
//场景类
public class Client {
public static void main(String[] args) {
//创建一封TEXT格式的邮件
MailTemplate m = new HtmlMail("a@a.com", "b@b.com", "外星人攻击地球了!", "结局是外星人被地球人打败了!");
//创建一个Mail发送程序
MailServer mail = new Postfix(m);
//发送邮件
mail.sendMail();
}
}
2.门面模式 VS 中介模式
门面模式为复杂的子系统提供一个统一的访问界面,它定义的是一个高层接口,该接口使得子系统更加容易使用,避免外部模块深入到子系统内部而产生与子系统内细节耦合的问题。
中介者模式使用一个中介对象来封装一系列同事对象的交互行为,它使各对象之间不再显示地引用,从而使其耦合松散,建立一个可扩展的应用框架。
中介者模式实现工资计算
//抽象同事类
abstract class AbsColleague{
//每个同事类都对中介者非常了解
protected AbsMediator mediator;
public AbsColleague(AbsMediator mediator) {
this.mediator = mediator;
}
}
//职位接口
interface IPosition{
//升职
public void promote();
//降职
public void demote();
}
//职位
class Position extends AbsColleague implements IPosition{
public Position(AbsMediator mediator) {
super(mediator);
}
public void promote() {
super.mediator.down(this);
}
public void demote() {
super.mediator.up(this);
}
}
//工资接口
interface ISalary{
//加薪
public void increaseSalary();
//降薪
public void decreaseSalary();
}
//工资
class Salary extends AbsColleague implements ISalary{
public Salary(AbsMediator mediator) {
super(mediator);
}
public void increaseSalary() {
super.mediator.down(this);
}
public void decreaseSalary() {
super.mediator.up(this);
}
}
//税收接口
interface ITax{
//税收上升
public void raise();
//税收下降
public void drop();
}
//税收
class Tax extends AbsColleague implements ITax{
//注入中介者
public Tax(AbsMediator mediator) {
super(mediator);
}
public void drop() {
super.mediator.down(this);
}
public void raise() {
super.mediator.up(this);
}
}
//抽象中介者
abstract class AbsMediator{
//工资
protected final ISalary salary;
//职位
protected final IPosition position;
//税收
protected final ITax tax;
public AbsMediator() {
salary = new Salary(this);
position = new Position(this);
tax = new Tax(this);
}
//工资增加了
public abstract void up(ISalary salary);
//职位提升了
public abstract void up(IPosition position);
//税收提升了
public abstract void up(ITax Tax);
//工资降低了
public abstract void down(ISalary salary);
//职位降低了
public abstract void down(IPosition position);
//税收降低了
public abstract void down(ITax tax);
}
//中介者
class Mediator extends AbsMediator{
//工资增加了
public void up(ISalary salary) {
upSalary();
upTax();
}
//职位提升了
public void up(IPosition position) {
upPosition();
upSalary();
upTax();
}
//税收增加了
public void up(ITax Tax) {
upTax();
downSalary();
}
//以下同理
public void down(ISalary salary) {}
public void down(IPosition position) {}
public void down(ITax tax) {}
private void upSalary() {}
private void upTax() {}
private void upPosition() {}
private void downSalary() {}
private void downTax() {}
private void downPosition() {}
}
门面模式实现工资计算
//考勤情况
class Attendance{
//得到出勤天数
public int getWorkDays() {
return (new Random()).nextInt(30);
}
}
//奖金计算
class Bonus{
//考勤情况
private Attendance atte = new Attendance();
//奖金
public int getBonus() {
//获得出勤情况
int workDays = atte.getWorkDays();
//奖金计数器
int bonus = workDays * 1800 /30;
return bonus;
}
}
//基本工资
class BasicSalary{
//获得一个人的基本工资
public int getBasicSalary() {
return 2000;
}
}
//绩效
class Performance{
//基本工资
private BasicSalary salary = new BasicSalary();
//绩效奖励
public int getPerformanceValue() {
//随机绩效
int perf = (new Random()).nextInt(100);
return salary.getBasicSalary() * perf /100;
}
}
//税收
class Tax{
//获取多少税金
public int getTax() {
//交纳一个随机数量的税金
return (new Random()).nextInt(300);
}
}
//总资金计算
class SalaryProvider{
//基本工资
private BasicSalary basicSalary = new BasicSalary();
//奖金
private Bonus bonus = new Bonus();
//绩效
private Performance perf = new Performance();
//税收
private Tax tax = new Tax();
//获得用户的总收入
public int totalSalary() {
return basicSalary.getBasicSalary()+bonus.getBonus()+perf.getPerformanceValue()-tax.getTax();
}
}
//HR门面
class HRFacade{
//总工资情况
private SalaryProvider salaryProvider = new SalaryProvider();
//考勤情况
private Attendance attendance = new Attendance();
//查询一个人的总收入
public int querySalary(String name,Date date) {
return salaryProvider.totalSalary();
}
//查询一个员工一个月工作了多少天
public int queryWorkDays(String name) {
return attendance.getWorkDays();
}
}
//场景类
public class Client {
public static void main(String[] args) {
//定义门面
HRFacade facade = new HRFacade();
int salary = facade.querySalary("张三", new Date(System.currentTimeMillis()));
System.out.println("张三 11月 总收入为:"+salary);
//再查询出勤天数
int workDays = facade.queryWorkDays("李四");
System.out.println("李四 本月出勤:"+workDays);
}
}