一、本课目标
- 实现“动态组装”的打印机
二、依赖注入综合实例
2.1如何开发一个打印机?
- 可灵活配置使用彩色墨盒或灰色墨盒
- 可灵活配置打印页面的大小
这两个灵活就是动态体现的地方。
分析:
打印机功能的实现依赖于墨盒和纸张。
步骤:
1、定义墨盒和纸张的接口标准
2、使用接口标准开发打印机
3、组装打印机
4、运行打印机
定义墨盒和纸张的接口标准
墨盒的接口标准
package cn.printer;
public interface Ink {
/**
* 定义打印机采用的颜色值
* @param r 红色值
* @param g 绿色值
* @param b 蓝色值
* @return 打印机采用的颜色值
*/
public String getColor(int r, int g, int b);
}
墨盒的实现类:
package cn.ink;
import java.awt.Color;
import cn.printer.Ink;
/**
* 灰色墨盒,实现ink接口
* @author Administrator
*
*/
public class GreyInk implements Ink {
/**
* 打印采用灰色
*/
public String getColor(int r, int g, int b) {
int c = (r + g + b)/3;
Color color = new Color(c,c,c);
return "#" + Integer.toHexString(color.getRGB()).substring(2);
}
}
package cn.ink;
import java.awt.Color;
import cn.printer.Ink;
public class ColorInk implements Ink{
/**
* 打印采用彩色
*/
public String getColor(int r, int g, int b) {
Color color = new Color(r,g,b);
return "#" + Integer.toHexString(color.getRGB()).substring(2);
}
}
纸张的接口标准
package cn.printer;
/**
* 打印机采用的纸张接口
* @author Administrator
*
*/
public interface Paper {
public static final String newLine = "\r\n";
/**
* 往纸张里面逐个字符输出内容
* @param c
*/
public void putInChar(char c);
/**
* 得到输出到纸张的内容
* @return
*/
public String getContent();
}
纸张的实现类
package cn.ink;
import cn.printer.Paper;
public class TextPaper implements Paper{
// 每一行能输出的字符数
private int charPerLine = 16;
// 每页的行数
private int linePerPage = 8;
// 当前的横向位置,从0开始到charPerLine-1
private int posx = 0;
// 当前行号
private int posy = 0;
// 当前页号
private int posp = 1;
// 纸张中的内容
private String content = "";
public void putInChar(char c) {
content +=c;
++ posx;
// 判断是否换行
if (posx == charPerLine) {
content += Paper.newLine;
posx = 0;
++ posy;
}
// 判断是否换页
if (posy == linePerPage) {
content += "==第" + posp + "页==";
content += Paper.newLine + Paper.newLine;
posy = 0;
++ posp;
}
}
public String getContent() {
// 给页面加上页号
String ret = content;
if (!(posx == 0 && posy ==0)) {
int count = linePerPage - posy;
for (int i = 0; i < count; i++) {
ret += Paper.newLine;
}
ret += "==第" + posp + "页==";
}
return ret;
}
/**
* 设置注入所需要的setter方法,注入charPerLine的值
* @param charPerLine
*/
public void setCharPerLine(int charPerLine) {
this.charPerLine = charPerLine;
}
/**
* 设置注入所需要的setter方法,注入linePerPage的值
* @param linePerPage
*/
public void setLinePerPage(int linePerPage) {
this.linePerPage = linePerPage;
}
}
使用接口标准开发打印机
package cn.printer;
public class Printer {
// 面向接口编程,定义Ink接口的变量
private Ink ink;
// 面向接口编程,定义paper接口变量
private Paper paper;
/**
* 提供Ink的setter方法,以进行设值注入
* @param ink
*/
public void setInk(Ink ink) {
this.ink = ink;
}
/**
* 提供paper的setter方法,以进行设值注入
* @param paper
*/
public void setPaper(Paper paper) {
this.paper = paper;
}
/**
* 打印方法,查看打印采用的颜色和纸张中打印的内容
* @param str
*/
public void print(String str) {
System.out.println("使用" + ink.getColor(225, 200, 0) + "颜色打印\n");
for (int i = 0; i < str.length(); i++) {
paper.putInChar(str.charAt(i));
}
System.out.println(paper.getContent());
}
}
组装打印机:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 指定灰色墨盒的bean元素,该元素的id为greyInk,class属性指定要实例化的类 -->
<bean id="greyInk" class="cn.ink.GreyInk"></bean>
<!-- 指定彩色墨盒的bean元素,该元素的id为colorInk,class属性指定要实例化的类 -->
<bean id="colorInk" class="cn.ink.ColorInk"></bean>
<!-- 指定a4paper的bean元素,该元素的id为a4paper,class属性指定要实例化的类 -->
<bean id="a4paper" class="cn.ink.TextPaper">
<!-- property元素指定需要赋值的属性,charPerLine需要赋值,
TextPaper类里面需要写setCharPerLine(),进行设值注入 -->
<property name="charPerLine" value="8"></property>
<!-- property元素指定需要赋值的属性,linePerPage需要赋值,
TextPaper类里面需要写setlLinePerPage(),进行设值注入 -->
<property name="linePerPage" value="6"></property>
</bean>
<!-- 指定b5paper的bean元素,该元素的id为b5paper,class属性指定要实例化的类 -->
<bean id="b5paper" class="cn.ink.TextPaper">
<!-- property元素指定需要赋值的属性,charPerLine需要赋值,
TextPaper类里面需要写setCharPerLine(),进行设值注入 -->
<property name="charPerLine" value="6"></property>
<!-- property元素指定需要赋值的属性,linePerPage需要赋值,
TextPaper类里面需要写setlLinePerPage(),进行设值注入 -->
<property name="linePerPage" value="5"></property>
</bean>
<!-- 指定打印机的bean元素,该元素的id为printer,class属性指定要实例化的类 -->
<bean id="printer" class="cn.printer.Printer">
<!-- property元素指定需要赋值的属性,ink需要赋值,
Printer类里面需要写setInk(),进行设值注入 -->
<property name="ink" ref="greyInk"></property>
<!-- property元素指定需要赋值的属性,paper需要赋值,
Printer类里面需要写setPaper(),进行设值注入 -->
<property name="paper" ref="b5paper"></property>
</bean>
</beans>
测试打印机:
package test;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.printer.Printer;
public class PrinterTest {
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
Printer printer = (Printer) context.getBean("printer");
String content = "我有一句mmpasdfgsali劳动法和披萨了对方【‘安慰放到【 按时交电费【后我完全士大夫is阿道夫撒欢打发时间地方撒旦00"
+ "sdfljasdhi;fioID返回记录暗示欧大佛按时交路口的法律健身房的阿士大夫为就爱上对方的舒服啊圣诞节阿萨德和劳动法护师返回去"
+ "披萨底价阿发碎对方拉丝机地方哈是否打算厉害的风景就立刻短时撒旦法撒旦法是发撒旦法撒的法国大撒发放大法官的说法噶是否噶啥的";
printer.print(content);
}
}
三、小结
在上一节的HelloSpring中,也是只定义了变量who,但是这个变量的值是卫东了,是依靠配置文件注入的。这一节的Textpaper类中的charPerLine和lineperPage也可以这么做,实现不定义值,依赖xml文件注入。这一节的打印机Printer类里面,也是只定义了ink和paper接口,但是没有实例化出来对象,对象是通过set方法在xml文件中注入进来的。
所以,可以通过set方法注入变量(helloSpring)、实例对象(printer)。
还可以在xml文件中给同一个变量设置不同的注入值,从而得到不同的对象(textpaper)。