最近在看《 Effective Java 》这本书,里面提到了编码时需要注意【 保护性拷贝(Rule39) 】,这里备份下实现的注意点,截图版权属于原作者。
github:
【 https://github.com/cstriker1407/think_in_java 】
首先列出基本类:
class Rule39Bean { public int value; public Rule39Bean(int value) { this.value = value; } public Rule39Bean(Rule39Bean bean) { this.value = bean.value; } } abstract class Period { public Period(Rule39Bean small, Rule39Bean big) { } protected Rule39Bean small; protected Rule39Bean big; public void check() { if (small.value < big.value) { System.out.println("Right!! small < big"); }else { System.out.println("Wrong!! small >= big"); } } public Rule39Bean getBig() { return big; } }
使用方式A,有缺陷,未加任何保护:
class PeriodA extends Period { public PeriodA(Rule39Bean small, Rule39Bean big) { super(small, big); this.small = small; this.big = big; if (small.value >= big.value) { throw new IllegalArgumentException("small >= big"); } } }
测试代码:
{ Rule39Bean small = new Rule39Bean(10); Rule39Bean big = new Rule39Bean(20); PeriodA periodA = new PeriodA(small, big); periodA.check(); big.value = 5;//修改成功 periodA.check(); }
使用方式B,有缺陷,保护了构造函数,但是没有保护获取方法:
class PeriodB extends Period { public PeriodB(Rule39Bean small, Rule39Bean big) { super(small, big); this.small = new Rule39Bean(small); this.big = new Rule39Bean(big); if (small.value >= big.value) { throw new IllegalArgumentException("small >= big"); } } }
测试代码:
{ Rule39Bean small = new Rule39Bean(10); Rule39Bean big = new Rule39Bean(20); PeriodB periodB = new PeriodB(small, big); periodB.check(); big.value = 5;//修改失败 periodB.check(); periodB.getBig().value = 5;//修改成功 periodB.check(); }
使用方式C,在B的基础上增加了对获取方式的保护:
class PeriodC extends PeriodB { public PeriodC(Rule39Bean small, Rule39Bean big) { super(small, big); } @Override public Rule39Bean getBig() { return new Rule39Bean(big); } }
测试代码:
{ Rule39Bean small = new Rule39Bean(10); Rule39Bean big = new Rule39Bean(20); PeriodC periodC = new PeriodC(small, big); periodC.check(); big.value = 5;//修改失败 periodC.check(); periodC.getBig().value = 5;//修改失败 periodC.check(); }
原书介绍:
发表评论