早上,我去鸡蛋饼小摊拿买了一块鸡蛋饼,加了两煎蛋,加了火腿肠,加了生菜,还加了根油条。
吃的好饱。。。
人与动物区别在于,人不仅会吃,而且会思考。所以,这种场景,作为程序员,你应该怎么设计?
好说!
/**
* 反面教材1(BOOM!类爆炸)
*/
class 鸡蛋饼{
public double cost() {
return 3;
}
}
class 鸡蛋饼With鸡蛋 extends 鸡蛋饼{
public double cost() {
return super.cost() + 0.5;
}
}
class 鸡蛋饼With火腿 extends 鸡蛋饼{
public double cost() {
return super.cost() + 1;
}
}
/**
* 反面教材2(违反开闭原则:类应该对扩展开放,对修改关闭)
* 以后鸡蛋价格变了,或者加两个鸡蛋,或者再加一种别的调料,想一下你怎么设计?
*/
class 鸡蛋饼2{
/**
*有鸡蛋
*/
private boolean hasEgg;
/**
*有火腿
*/
private boolean hasHuotui;
public double cost() {
double basecost =3;
if(hasEgg) {
basecost +=0.5;
}
if(hasHuotui) {
basecost +=1;
}
return basecost;
}
/**
* @return the hasEgg
*/
public boolean isHasEgg() {
return hasEgg;
}
/**
* @param hasEgg the hasEgg to set
*/
public void setHasEgg(boolean hasEgg) {
this.hasEgg = hasEgg;
}
/**
* @return the hasHuotui
*/
public boolean isHasHuotui() {
return hasHuotui;
}
/**
* @param hasHuotui the hasHuotui to set
*/
public void setHasHuotui(boolean hasHuotui) {
this.hasHuotui = hasHuotui;
}
}
装饰者概念
动态地将责任附加到对象上,若要扩展功能,装饰者提供比继承更有弹性的替代方案。
设计理念
当我们设计的类不能满足我们的需求的时候,我们可能设计一个类去继承它,但是这样就会使对象之间高度的耦合。
这时,我们就可以换一种思路,将不能满足我们需求的类A嵌入到要扩展的功能的类B当中。
这里注意,我们将要扩展的功能设计为一个类B,当这个类构造时可以引入A,B将持有A对象实例。
这种方法,我们称之为:装饰者模式
使用场景
装饰模式的应用在java的I/O流中最为显著。
设计原则
对扩展开放,对修改关闭。
UML类图

示例
抽象组件
package com.study.headfirst.decorator;
/**
* 抽象组件
* @author mdl
* @date 2019/12/05
*/
public abstract class Pancake {
public String desc = "我不是一个具体的饼";
/**
* @return the desc
*/
public String getDesc() {
return desc;
}
public abstract double cost();
}
鸡蛋饼(具体组件A)
package com.study.headfirst.decorator;
/**
* @author mdl
* @date 2019/12/05
*/
public class TornCake extends Pancake{
public TornCake() {
desc ="鸡蛋饼";
}
/* (non-Javadoc)
* @see com.study.headfirst.decorator.Pancake#cost()
*/
@Override
public double cost() {
// TODO Auto-generated method stub
return 4;
}
}
肉夹馍(具体组件B)
package com.study.headfirst.decorator;
/**
* @author mdl
* @date 2019/12/05
*/
public class Roujiamo extends Pancake{
public Roujiamo() {
desc ="肉夹馍";
}
/* (non-Javadoc)
* @see com.study.headfirst.decorator.Pancake#cost()
*/
@Override
public double cost() {
// TODO Auto-generated method stub
return 5;
}
}
抽象装饰者
package com.study.headfirst.decorator;
/**
* 抽象装饰者
* @author mdl
* @date 2019/12/05
*/
public abstract class Condiment extends Pancake{
public abstract String getDesc();
}
鸡蛋(具体装饰者)
package com.study.headfirst.decorator;
/**
* 鸡蛋(具体装饰者)
* @author mdl
* @date 2019/12/05
*/
public class Egg extends Condiment{
private Pancake cake;
public Egg(Pancake cake) {
this.cake = cake;
}
/* (non-Javadoc)
* @see com.study.headfirst.decorator.Condiment#desc()
*/
@Override
public String getDesc() {
// TODO Auto-generated method stub
return cake.getDesc() + ",鸡蛋";
}
/* (non-Javadoc)
* @see com.study.headfirst.decorator.Pancake#cost()
*/
@Override
public double cost() {
// TODO Auto-generated method stub
return cake.cost() + 1;
}
}
火腿(具体装饰者)

package com.study.headfirst.decorator;
/**
* 火腿(具体装饰者)
* @author mdl
* @date 2019/12/05
*/
public class Ham extends Condiment{
private Pancake cake;
public Ham(Pancake cake) {
this.cake = cake;
}
/* (non-Javadoc)
* @see com.study.headfirst.decorator.Condiment#desc()
*/
@Override
public String getDesc() {
// TODO Auto-generated method stub
return cake.getDesc() + ", 火腿";
}
/* (non-Javadoc)
* @see com.study.headfirst.decorator.Pancake#cost()
*/
@Override
public double cost() {
// TODO Auto-generated method stub
return cake.cost() + 1.5;
}
}
生菜(具体装饰者)

package com.study.headfirst.decorator;
/**
* 生菜(具体装饰者)
* @author mdl
* @date 2019/12/05
*/
public class ShenCai extends Condiment{
private Pancake cake;
public ShenCai(Pancake cake) {
this.cake = cake;
}
/* (non-Javadoc)
* @see com.study.headfirst.decorator.Condiment#desc()
*/
@Override
public String getDesc() {
// TODO Auto-generated method stub
return cake.getDesc() + ", 生菜";
}
/* (non-Javadoc)
* @see com.study.headfirst.decorator.Pancake#cost()
*/
@Override
public double cost() {
// TODO Auto-generated method stub
return cake.cost() + 0.5;
}
}
测试
package com.study.headfirst.decorator;
/**
* @author mdl
* @date 2019/12/05
*/
public class Test {
public static void main(String[] args) {
// 点个鸡蛋饼,啥都不加
Pancake cake =new TornCake();
System.out.println(cake.getDesc() + ",价钱:" + cake.cost());
// 点个鸡蛋饼,加两根火腿,加生菜
Pancake cake2 =new TornCake();
cake2 =new Ham(cake2);
cake2 =new Ham(cake2);
cake2 =new ShenCai(cake2);
System.out.println(cake2.getDesc() + ",价钱:" + cake2.cost());
}
}

来源:https://www.cnblogs.com/bloodthirsty/p/12011024.html
