Java设计模式:装饰者模式(Decorator Pattern)

2023-11-19

装饰者模式,涉及的重要设计原则:类应该对扩展开放,对修改关闭

装饰者模式定义:

装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

UML类图:


装饰者模式事例:

咖啡店

咖啡种类:

1)深焙咖啡(DarkRoast)

2)家庭混合咖啡(HouseBlend)

3)浓咖啡(Espresso)

4)低咖啡因咖啡(Decaf)

5)其它咖啡。。。

咖啡调料:

1)摩卡(Mocha)

2)牛奶(Milk)

3)豆浆(Soy)

4)奶泡(Whip)

5)其它调料。。。

点单:

要一份加了摩卡和奶泡的深焙咖啡...等等

UML类图


代码实现:

Beverage.java

package com.jing.decorator;

/**
 * 所有饮料的抽象超类
 * @author LiuJing
 *
 */
public abstract class Beverage {

	/**
	 * 饮料的名字
	 */
	String description = "Unknow Beverage";
	
	/*
	 * 获取饮料的名字
	 */
	public String getDescription(){
		return description;
	}
	
	
	/***
	 * 获取饮料的价格
	 * @return 返回计算后的总价
	 */
	public abstract double cost();
	
}

DarkRoast.java

package com.jing.decorator;

import java.text.DecimalFormat;

/***
 * 深烤咖啡
 * @author LiuJing
 *
 */
public class DarkRoast extends Beverage {

	/***
	 * 构造时确定名字
	 */
	public DarkRoast(){
		description = "DarkRoast";
	}
	
	/***
	 * 价格
	 */
	public double cost() {
		double cost = 10.0;
		
		// 用于保存2位小数
		DecimalFormat df = new DecimalFormat("#.00");
		return Double.valueOf(df.format(cost));
	}
}

Decaf.java

package com.jing.decorator;

import java.text.DecimalFormat;

/***
 * 低咖啡因咖啡
 * @author LiuJing
 *
 */
public class Decaf extends Beverage {

	/***
	 * 构造时确定名字
	 */
	public Decaf() {
		description = "Decaf";
	}
	
	/***
	 * 价格
	 */
	public double cost() {
		double cost = 11.0;

		DecimalFormat df = new DecimalFormat("#.00");
		return Double.valueOf(df.format(cost));
	}
}

Espresso.java

package com.jing.decorator;

import java.text.DecimalFormat;

/***
 * 浓咖啡
 * @author LiuJing
 *
 */
public class Espresso extends Beverage {

	/***
	 *  构造时确定其名字
	 */
	public Espresso(){
		description = "Espresso";
	}
	
	/***
	 * 方法返回 该饮料的价格
	 */
	public double cost() {
		double cost = 12.0;
		
		DecimalFormat df = new DecimalFormat("#.00");
		return Double.valueOf(df.format(cost));
	}
}

HouseBlend.java

package com.jing.decorator;

import java.text.DecimalFormat;

/***
 * 家庭混合咖啡
 * @author LiuJing
 *
 */
public class HouseBlend extends Beverage {

	/***
	 * 构造时确定其名字
	 */
	public HouseBlend(){
		description = "HouseBlend";
	}
	
	/***
	 * 返回该咖啡的价格
	 */
	public double cost() {
		double cost = 13.0;
		
		DecimalFormat df = new DecimalFormat("#.00");
		return Double.valueOf(df.format(cost));
	}

}
CondimentDecorator.java

package com.jing.decorator;

/***
 * 调料装饰者抽象超类,继承至 Beverage,便于类型的统一,能彼此替换。
 * @author LiuJing
 *
 */
public abstract class CondimentDecorator extends Beverage {
	
	/***
	 * 用于保存要装饰的咖啡对象
	 */
	Beverage beverage;
	
	/***
	 * 所有子类都必须重新实现 getDescription()方法
	 */
	public abstract String getDescription();

}
Milk.java

package com.jing.decorator;

import java.text.DecimalFormat;

/***
 * 咖啡调料 牛奶  Milk >> CondimentDecorator >> Beverage
 * @author LiuJing
 *
 */
public class Milk extends CondimentDecorator {

	
	/**
	 * 构造时确定要加给谁
	 * @param beverage
	 */
	public Milk(Beverage beverage){
		this.beverage = beverage;
	}
	
	
	/***
	 * 不仅显示当前名,还说明被装饰的名字 
	 */
	@Override
	public String getDescription() {
		// TODO Auto-generated method stub
		return beverage.getDescription() + ", Milk";
	}

	/***
	 * 获取本身的价格和咖啡的价格
	 */
	@Override
	public double cost() {
		// TODO Auto-generated method stub
		double cost = beverage.cost();
		cost += 0.1;
		
		DecimalFormat df = new DecimalFormat("#.00");
		return Double.valueOf(df.format(cost));
	}

}

Mocha.java

package com.jing.decorator;

import java.text.DecimalFormat;

/***
 * 咖啡调料 摩卡 Mocha >> CondimentDecorator >> Beverage
 * 
 * @author LiuJing
 * 
 */
public class Mocha extends CondimentDecorator {


	/**
	 * 构造时确定要加给谁
	 * 
	 * @param beverage
	 */
	public Mocha(Beverage beverage) {
		this.beverage = beverage;
	}

	/***
	 * 不仅显示当前名,还说明被装饰的名字
	 */
	@Override
	public String getDescription() {
		// TODO Auto-generated method stub
		return beverage.getDescription() + ", Mocha";
	}

	/***
	 * 获取本身的价格和咖啡的价格
	 */
	@Override
	public double cost() {
		// TODO Auto-generated method stub
		double cost = beverage.cost();
		cost += 0.1;

		DecimalFormat df = new DecimalFormat("#.00");
		return Double.valueOf(df.format(cost));
	}

}
Soy.java

package com.jing.decorator;

import java.text.DecimalFormat;

/***
 * 咖啡调料 豆浆 Soy >> CondimentDecorator >> Beverage
 * 
 * @author LiuJing
 * 
 */
public class Soy extends CondimentDecorator {


	/**
	 * 构造时确定要加给谁
	 * 
	 * @param beverage
	 */
	public Soy(Beverage beverage) {
		this.beverage = beverage;
	}

	/***
	 * 不仅显示当前名,还说明被装饰的名字
	 */
	@Override
	public String getDescription() {
		// TODO Auto-generated method stub
		return beverage.getDescription() + ", Soy";
	}

	/***
	 * 获取本身的价格和咖啡的价格
	 */
	@Override
	public double cost() {
		// TODO Auto-generated method stub
		double cost = beverage.cost();
		cost += 0.1;

		DecimalFormat df = new DecimalFormat("#.00");
		return Double.valueOf(df.format(cost));
	}

}
Whip.java

package com.jing.decorator;

import java.text.DecimalFormat;

/***
 * 咖啡调料 奶泡 Whip >> CondimentDecorator >> Beverage
 * 
 * @author LiuJing
 * 
 */
public class Whip extends CondimentDecorator {


	/**
	 * 构造时确定要加给谁
	 * 
	 * @param beverage
	 */
	public Whip(Beverage beverage) {
		this.beverage = beverage;
	}

	/***
	 * 不仅显示当前名,还说明被装饰的名字
	 */
	@Override
	public String getDescription() {
		// TODO Auto-generated method stub
		return beverage.getDescription() + ", Whip";
	}

	/***
	 * 获取本身的价格和咖啡的价格
	 */
	@Override
	public double cost() {
		// TODO Auto-generated method stub
		double cost = beverage.cost();
		cost += 0.1;

		DecimalFormat df = new DecimalFormat("#.00");
		return Double.valueOf(df.format(cost));
	}

}
测试类

Test.java

package com.jing.decorator;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		
		// 点了一份浓咖啡
		Beverage beverage = new Espresso();
		System.out.println(
				beverage.getDescription() + ": $ " + beverage.cost());

		// 点了一份深烤
		Beverage beverage2 = new DarkRoast();
		beverage2 = new Mocha(beverage2);    // 加 摩卡装饰
		beverage2 = new Mocha(beverage2);    // 再加 摩卡装饰
		beverage2 = new Whip(beverage2);     // 再加 奶泡装饰
		System.out.println(
				beverage2.getDescription() + ": $ " + beverage2.cost());

		// 点了一份家庭混合
		Beverage beverage3 = new HouseBlend();
		beverage3 = new Soy(beverage3);   // 加 豆浆装饰
		beverage3 = new Mocha(beverage3); // 再加 摩卡装饰
		beverage3 = new Whip(beverage3);  // 再加 奶泡装饰
		System.out.println(
				beverage3.getDescription() + ": $ " + beverage3.cost());

		// 用 工厂模式 和 生成器模式,可以更好的建立被 装饰者对象
	}

}
输出:

Espresso: $ 12.0
DarkRoast, Mocha, Mocha, Whip: $ 10.3
HouseBlend, Soy, Mocha, Whip: $ 13.3

扩展:

现在咖啡要有区分 大,中,小杯的价格;

同理,

调料因为杯的大小也要区分不同的价格;

Beverage.java

package com.jing.decorator.size;

/**
 * 所有饮料的抽象超类
 * @author LiuJing
 *
 */
public abstract class Beverage {
	
	/**
	 * 杯子的容量类型
	 */
	public final static int TALL = 1;
	public final static int GRANDE = 2;
	public final static int VENTI = 3;
	
	/**
	 * 杯子的容量
	 */
	private int volume = 2; // 默认为中杯
	
	public int getSize() {
		return volume;
	}

	public void setSize(int valume) {
		this.volume = valume;
	}
	
	public String getSizeDescription() {
		
		String type = "未知杯的大小 ";
		switch(volume){
		case TALL:
			type = "小杯";
			break;
		case GRANDE:
			type = "中杯";
			break;
		case VENTI:
			type = "大杯";
			break;
		}

		return type;
	}

	/**
	 * 饮料的名字
	 */
	String description = "Unknow Beverage";
	

	
	/*
	 * 获取饮料的名字
	 */
	public String getDescription(){
		return description;
	}
	
	
	/***
	 * 获取饮料的价格
	 * @return 返回计算后的总价
	 */
	public abstract double cost();
	
}

DarkRoast.java

package com.jing.decorator.size;

import java.text.DecimalFormat;

/***
 * 深烤咖啡
 * @author LiuJing
 *
 */
public class DarkRoast extends Beverage {

	/***
	 * 构造时确定名字
	 */
	public DarkRoast(){
		description = "DarkRoast";
	}
	
	public DarkRoast(int volume){
		setSize(volume);
		description = "DarkRoast";
	}
	
	/***
	 * 价格
	 */
	public double cost() {
		double cost = 0.0;
		if (getSize() == Beverage.TALL) {
			cost = 10.0;
		}else if (getSize() == Beverage.GRANDE){
			cost = 15.0;
		}else if (getSize() == Beverage.VENTI){
			cost = 20.0;
		}
		
		DecimalFormat df = new DecimalFormat("#.00");
		return Double.valueOf(df.format(cost));
	}

}
Decaf.java

package com.jing.decorator.size;

import java.text.DecimalFormat;

/***
 * 低咖啡因咖啡
 * @author LiuJing
 *
 */
public class Decaf extends Beverage {

	/***
	 * 构造时确定名字
	 */
	public Decaf() {
		description = "Decaf";
	}
	public Decaf(int volume){
		setSize(volume);
		description = "Decaf";
	}
	
	/***
	 * 价格
	 */
	public double cost() {
		double cost = 0.0;
		if (getSize() == Beverage.TALL) {
			cost = 11.0;
		}else if (getSize() == Beverage.GRANDE){
			cost = 16.0;
		}else if (getSize() == Beverage.VENTI){
			cost = 21.0;
		}
		
		DecimalFormat df = new DecimalFormat("#.00");
		return Double.valueOf(df.format(cost));
	}

}
Espresso.java

package com.jing.decorator.size;

import java.text.DecimalFormat;

/***
 * 浓咖啡
 * @author LiuJing
 *
 */
public class Espresso extends Beverage {

	/***
	 *  构造时确定其名字
	 */
	public Espresso(){
		description = "Espresso";
	}
	
	public Espresso(int volume){
		setSize(volume);
		description = "Espresso";
	}
	
	/***
	 * 方法返回 该饮料的价格
	 */
	public double cost() {
		double cost = 0.0;
		if (getSize() == Beverage.TALL) {
			cost = 12.0;
		}else if (getSize() == Beverage.GRANDE){
			cost = 17.0;
		}else if (getSize() == Beverage.VENTI){
			cost = 22.0;
		}
		
		DecimalFormat df = new DecimalFormat("#.00");
		return Double.valueOf(df.format(cost));
	}
}

HouseBlend.java

package com.jing.decorator.size;

import java.text.DecimalFormat;

/***
 * 家庭混合咖啡
 * @author LiuJing
 *
 */
public class HouseBlend extends Beverage {

	/***
	 * 构造时确定其名字
	 */
	public HouseBlend(){
		description = "HouseBlend";
	}
	
	public HouseBlend(int volume){
		setSize(volume);
		description = "HouseBlend";
	}
	
	/***
	 * 返回该咖啡的价格
	 */
	public double cost() {
		double cost = 0.0;
		if (getSize() == Beverage.TALL) {
			cost = 13.0;
		}else if (getSize() == Beverage.GRANDE){
			cost = 18.0;
		}else if (getSize() == Beverage.VENTI){
			cost = 23.0;
		}
		
		DecimalFormat df = new DecimalFormat("#.00");
		return Double.valueOf(df.format(cost));
	}

}

CondimentDecorator.java

package com.jing.decorator.size;

/***
 * 调料装饰者抽象超类,继承至 Beverage,便于类型的统一,能彼此替换。
 * @author LiuJing
 *
 */
public abstract class CondimentDecorator extends Beverage {
	
	/***
	 * 要装饰的咖啡对象
	 */
	Beverage beverage;
	
	
	/***
	 * 所有子类都必须重新实现 getDescription()方法
	 */
	public abstract String getDescription();

}

Milk.java

package com.jing.decorator.size;

import java.text.DecimalFormat;

/***
 * 咖啡调料 牛奶  Milk >> CondimentDecorator >> Beverage
 * @author LiuJing
 *
 */
public class Milk extends CondimentDecorator {


	/**
	 * 构造时确定要加给谁
	 * @param beverage
	 */
	public Milk(Beverage beverage){
		this.beverage = beverage;
		setSize(beverage.getSize());
	}
	
	public int getSize(){
		return beverage.getSize();
	}
	
	/***
	 * 不仅显示当前名,还说明被装饰的名字 
	 */
	@Override
	public String getDescription() {
		// TODO Auto-generated method stub
		return beverage.getDescription() + ", Milk";
	}

	/***
	 * 获取本身的价格和咖啡的价格
	 */
	@Override
	public double cost() {
		// TODO Auto-generated method stub
		double cost = beverage.cost();
		if (getSize() == Beverage.TALL){
			cost += 0.1;
		} else if (getSize() == Beverage.GRANDE){
			cost += 0.2;
		} else if (getSize() == Beverage.VENTI){
			cost += 0.3;
		}
		
		DecimalFormat df = new DecimalFormat("#.00");
		return Double.valueOf(df.format(cost));
	}

}
Mocha.java

package com.jing.decorator.size;

import java.text.DecimalFormat;

/***
 * 咖啡调料 摩卡 Mocha >> CondimentDecorator >> Beverage
 * @author LiuJing
 *
 */
public class Mocha extends CondimentDecorator {

	
	/**
	 * 构造时确定要加给谁
	 * @param beverage
	 */
	public Mocha(Beverage beverage){
		this.beverage = beverage;
		setSize(beverage.getSize());
	}
	
	public int getSize(){
		return beverage.getSize();
	}
	
	/***
	 * 不仅显示当前名,还说明被装饰的名字 
	 */
	@Override
	public String getDescription() {
		// TODO Auto-generated method stub
		return beverage.getDescription() + ", Mocha";
	}

	/***
	 * 获取本身的价格和咖啡的价格
	 */
	@Override
	public double cost() {
		// TODO Auto-generated method stub
		double cost = beverage.cost();
		if (getSize() == Beverage.TALL){
			cost += 0.1;
		} else if (getSize() == Beverage.GRANDE){
			cost += 0.2;
		} else if (getSize() == Beverage.VENTI){
			cost += 0.3;
		}
		
		DecimalFormat df = new DecimalFormat("#.00");
		return Double.valueOf(df.format(cost));
	}

}

Soy.java

package com.jing.decorator.size;

import java.text.DecimalFormat;

/***
 * 咖啡调料 豆浆  Soy >> CondimentDecorator >> Beverage
 * @author LiuJing
 *
 */
public class Soy extends CondimentDecorator {

	
	/**
	 * 构造时确定要加给谁
	 * @param beverage
	 */
	public Soy(Beverage beverage){
		this.beverage = beverage;
		setSize(beverage.getSize());
	}
	
	public int getSize(){
		return beverage.getSize();
	}
	
	/***
	 * 不仅显示当前名,还说明被装饰的名字 
	 */
	@Override
	public String getDescription() {
		// TODO Auto-generated method stub
		return beverage.getDescription() + ", Soy";
	}

	/***
	 * 获取本身的价格和咖啡的价格
	 */
	@Override
	public double cost() {
		// TODO Auto-generated method stub
		double cost = beverage.cost();
		if (getSize() == Beverage.TALL){
			cost += 0.1;
		} else if (getSize() == Beverage.GRANDE){
			cost += 0.2;
		} else if (getSize() == Beverage.VENTI){
			cost += 0.3;
		}
		
		DecimalFormat df = new DecimalFormat("#.00");
		return Double.valueOf(df.format(cost));
	}

}
Whip.java

package com.jing.decorator.size;

import java.text.DecimalFormat;

/***
 * 咖啡调料 奶泡  Whip >> CondimentDecorator >> Beverage
 * @author LiuJing
 *
 */
public class Whip extends CondimentDecorator {


	/**
	 * 构造时确定要加给谁
	 * @param beverage
	 */
	public Whip(Beverage beverage){
		this.beverage = beverage;
		setSize(beverage.getSize());
	}
	
	public int getSize(){
		return beverage.getSize();
	}
	
	/***
	 * 不仅显示当前名,还说明被装饰的名字 
	 */
	@Override
	public String getDescription() {
		// TODO Auto-generated method stub
		return beverage.getDescription() + ", Whip";
	}

	/***
	 * 获取本身的价格和咖啡的价格
	 */
	@Override
	public double cost() {
		// TODO Auto-generated method stub
		double cost = beverage.cost();
		if (getSize() == Beverage.TALL){
			cost += 0.1;
		} else if (getSize() == Beverage.GRANDE){
			cost += 0.2;
		} else if (getSize() == Beverage.VENTI){
			cost += 0.3;
		}
		
		DecimalFormat df = new DecimalFormat("#.00");
		return Double.valueOf(df.format(cost));
	}

}
Test.java

package com.jing.decorator.size;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		
		// 点了一份浓咖啡
		Beverage beverage = new Espresso(); // 使用默认中杯
		System.out.println(beverage.getSizeDescription()
				+ beverage.getDescription() + ": $ " + beverage.cost());

		// 点了一份深烤
		Beverage beverage2 = new DarkRoast();// 默认为中号
		beverage2.setSize(Beverage.TALL);    // 重新设置杯号为小号
		beverage2 = new Mocha(beverage2);    // 加 摩卡装饰
		beverage2 = new Mocha(beverage2);    // 再加 摩卡装饰
		beverage2 = new Whip(beverage2);     // 再加 奶泡装饰
		System.out.println(beverage2.getSizeDescription()
				+ beverage2.getDescription() + ": $ " + beverage2.cost());

		// 点了一份家庭混合
		Beverage beverage3 = new HouseBlend(Beverage.VENTI); // 构造初始时就设为大号
		beverage3 = new Soy(beverage3);   // 加 豆浆装饰
		beverage3 = new Mocha(beverage3); // 再加 摩卡装饰
		beverage3 = new Whip(beverage3);  // 再加 奶泡装饰
		System.out.println(beverage3.getSizeDescription()
				+ beverage3.getDescription()
				+ ": $ " + beverage3.cost());

		// 用 工厂模式 和 生成器模式,可以更好的建立被 装饰者对象
	}

}

输出:

中杯Espresso: $ 17.0
小杯DarkRoast, Mocha, Mocha, Whip: $ 10.3
大杯HouseBlend, Soy, Mocha, Whip: $ 23.9

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java设计模式:装饰者模式(Decorator Pattern) 的相关文章

  • IntelliJ IDEA中代码被覆盖了怎么恢复

    在你git pull 拉去代码的时候 在IntelliJ IDEA中一不小心将你本地代码给覆盖了 这个时候 你撤回是无效的时候 是不是有点小激动 还有点小慌 辛辛苦苦写的代码没啦 被覆盖了 不要慌 只要用的是IntelliJ IDEA这个工

随机推荐

  • javaの日志级别

    最近几周给项目补日志 头都大了 项目开发接口时一定要同步日志 一定 首先 日志级别从低到高 all
  • 网络安全应急响应操作流程-打好应急响应保卫战

    文章目录 应急响应 应急响应目标 应急响应标准流程 事前 事中 检测 响应 处置 溯源 人的识别 核心注意事项 参考文献 应急响应 应急响应是安全工作的重点和难点 由于响应过程中压力比较大 难免出现手忙脚乱的情况 因此怎样做好应急响应工作是
  • router和route的区别

    简单理解为 route是用来获取路由信息的 router是用来操作路由的 一 router router是VueRouter的实例 通过Vue use VueRouter 和VueRouter构造函数得到一个router的实例对象 这个对象
  • List、Queue

    1 ArrayList 底层是基于动态数组的数据结构 是有存放顺序的 2 LinkedList 底层是基于双链表的数据结构 每一个存储单元 都涉及到其他两个引用 优缺点 在执行get set 时 ArrayList的效率高 LinkedLi
  • Matlab产生离散正弦信号即绘制频谱图

    假设正弦信号频率为f0 40000Hz 采样频率fs 160000Hz 注意 fs必须大于2f0 否则采到的点根本不是正弦 实际上 fs 4f0是比较合适的 Matlab程序如下 function y gensinx f0 fs n N f
  • [YOLO专题-27]:YOLO V5 小目标检测遇到的问题与常见解决办法

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 YOLO专题 27 YOLO V5 小目标检测遇到的问题与常见解决办法 文火冰糖 王文兵 的博客 CSDN博客 目录 第1章 前言 第2章
  • freeswitch二、freeswitch之注册,呼叫接听测试

    在上一篇文章中讲解了freeswitch的安装方法 安装完后测试了和数据库的交互 下面就要测试一下freeswitch的功能了 freeswitch测试 freeswitch的conf目录中有20个默认的sip账号 可以直接做简单的测试 其
  • sys用户下为其他用户的创建私有db link的案例

    文章目录 1 查询job执行情况 2 确认根因 3 重建DB LINK 3 1使用current schema方式 3 2使用procedure方式 4 重新编译失效的对象 并手动执行job 记录一下scheduler job执行失败 而不
  • 类型“ScriptManager”的控件“ScriptManager1”必须放在具有 runat=server 的窗体标记内。...

  • 表单提交Post方法、Get方法背后的秘密

    表单大家都很熟悉 上网的时候经常会遇到表单 表单用来接受用户的输入 并将用户的输入以 name value值对 集合的形式提交到服务器进行处理 那么表单是怎样将数据提交到服务器的 服务器是怎样对表单数据进行处理的 下面我将为大家揭开表单提交
  • 数据中台-让数据用起来-6

    文章目录 第六章 数据开发 数据价值提炼工厂 6 1 数据计算能力的4种类型 6 1 1 批计算 6 1 2 流计算 6 1 3 在线查询 6 1 4 即席分析 6 2 离线开发 1 作业调度 2 基线控制 3 异构存储 4 代码校验 5
  • Tomcat 服务器的使用(IDEA 2021.3)

    目录 1 Tomcat 下载和安装 2 IDEA 创建 JavaWeb 项目 3 IDEA 集成 Tomcat 并发布项目 服务器是计算机的一种 它比普通计算机运行更快 负载更高 价格更贵 服务器在网络中为其它客户机 如PC机 智能设备等
  • 精致的动画特效源代码

    动画特效 css简介 代码部分 纯css3云彩动画效果 css3放大镜动画效果 jQuery游戏图片手风琴收缩切换特效 js百叶窗图片3D旋转切换特效 纯CSS3制作飞舞的火箭动画 简单易用的纯CSS3图片墙效果 一个简单好看的纯CSS3翻
  • 【风格迁移系列三】(Adain)Arbitrary Style Transfer in Real-time with Adaptive Instance Normalization 论文解读

    最近看了这篇论文 Arbitrary Style Transfer in Real time with Adaptive Instance Normalization 由于没有详细的博客参考 还是花了一些时间来阅读论文 于是提出自己对论文的
  • 代码随想录算法训练营第一天

    Leetcode704 二分查找 题目链接 关键词 二分查找 循环不变量 区间 问题思路 二分查找的应用 关键在于循环过程中区间的维护 记住循环不变量原则 在这个问题中循环不变量是区间的定义 注意左闭右开和左开右闭的区别 class Sol
  • Apache POI组件操作Excel

    Apache的POI组件是Java操作Microsoft Office办公套件的强大API 其中对Word Excel和PowperPoint都有支持 当然使用较多的还是Excel 因为Word和PowerPoint用程序动态操作的应用较少
  • proto学习

    介绍 protocol buffers 是一种语言无关 平台无关 可扩展的序列化结构数据的方法 它可用于通信协议 数据存储等 protocol buffers的接口 c java python API doc link https deve
  • 用Python画一个生日蛋糕并写上生日祝福对象及生日祝福语

    用Python画一个生日蛋糕并写上生日祝福对象及生日祝福语 画一个双层蛋糕并点上蜡烛 代码运行时间较长 请静待惊喜出现 代码运行截图 完整程序代码 干货主要有 200 多本 Python 电子书 和经典的书籍 应该有 Python标准库资料
  • 掌握 Ajax,第 7 部分: 在请求和响应中使用 XML

    偶尔使用 Ajax 的开发人员也会注意到 Ajax 中的 x 并意识到它代表 XML XML 是编程中最常用的数据格式之一 对于异步应用程序中的服务器响应能够带来切实的好处 在本文中 您将看到服务器如何在请求响应中发送 XML 现在如果不使
  • Java设计模式:装饰者模式(Decorator Pattern)

    装饰者模式 涉及的重要设计原则 类应该对扩展开放 对修改关闭 装饰者模式定义 装饰者模式动态地将责任附加到对象上 若要扩展功能 装饰者提供了比继承更有弹性的替代方案 UML类图 装饰者模式事例 咖啡店 咖啡种类 1 深焙咖啡 DarkRoa