1.用于扩展一个类的功能或者 给一个类添加附加职责。
2.动态的给一个对象添加功能,这些功能可以再动态的撤销。
public abstract class Battercake {
protected abstract String getMsg();
protected abstract int getPrice();
}
public class BaseBattercake extends Battercake {
@Override
protected String getMsg() {
return "煎饼";
}
@Override
protected int getPrice() {
return 5;
}
}
public abstract class BattercakeDecorator extends Battercake {
Battercake battercake;
public BattercakeDecorator(Battercake battercake) {
this.battercake = battercake;
}
@Override
protected String getMsg() {
return this.battercake.getMsg();
}
@Override
protected int getPrice() {
return this.battercake.getPrice();
}
}
public class EggDecorator extends BattercakeDecorator{
public EggDecorator(Battercake battercake) {
super(battercake);
}
@Override
protected String getMsg() {
return super.getMsg() + "+1个鸡蛋";
}
@Override
protected int getPrice() {
return super.getPrice() + 1;
}
}
public class SausageDecorator extends BattercakeDecorator{
public SausageDecorator(Battercake battercake) {
super(battercake);
}
@Override
protected String getMsg() {
return super.getMsg() + "+1根香肠";
}
@Override
protected int getPrice() {
return super.getPrice() + 2;
}
}
public class BattercakeTest {
public static void main(String[] args) {
Battercake battercake;
// 路边
battercake = new BaseBattercake();
//想加一个鸡蛋
battercake = new EggDecorator(battercake);
// 再加一个鸡蛋
battercake = new EggDecorator(battercake);
// 再加一根香肠
battercake = new SausageDecorator(battercake);
System.out.println(battercake.getMsg() + ",总价:" + battercake.getPrice());
}
}
优点:
1.装饰者时继承的有力补充,比继承灵活,不改变原有对象的情况下动态的给一个对象扩展功能,即插即用。
2.通过使用不同装配类一级这些中装饰类的排列组合,可以实现不同效果。
3.装饰者完全遵守开闭原则。
缺点:
1.会出现更多的代码,更多的类,增加程序复杂性。
2.动态装饰时,多层装饰时会更复杂。
// 被观察者
public class GPer extends Observable {
private String name = "GPer生态圈";
private static GPer gper = null;
public GPer() {
}
public static GPer getInstance() {
if (null == gper) {
gper = new GPer();
}
return gper;
}
public String getName() {
return name;
}
public void publishQuestion(Question question) {
System.out.println(question.getUseName() + "在" + this.name + "提交" + question.getContent());
setChanged();
notifyObservers(question);
}
}
public class Question {
private String useName;
private String content;
public String getUseName() {
return useName;
}
public void setUseName(String useName) {
this.useName = useName;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
// 观察者
public class Teacher implements Observer {
private String name;
public Teacher(String name) {
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
GPer g = (GPer) o;
Question question = (Question) arg;
System.out.println("==============================");
System.out.println(name + "老师,您好:\n" + "您收到一个来自" + g.getName() + "的提问,希望您解答,问题内容如下:\n" +
question.getContent() + "\n" + "提问者:" + question.getUseName());
}
}
public class ObserverTest {
public static void main(String[] args) {
GPer gPer = GPer.getInstance();
Teacher tom = new Teacher("Tom");
Teacher mic = new Teacher("mic");
Question question = new Question();
question.setUseName("小明");
question.setContent("观察者设计模式使用那些场景?");
gPer.addObserver(tom);
gPer.addObserver(mic);
gPer.publishQuestion(question);
}
}
/**
* 监听器的一种包装,标准事件源格式的定义
*/
public class Event {
//事件源,事件是由谁发起的保存起来
private Object source;
//事件触发,要通知谁
private Object target;
//事件触发,要做什么动作,回调
private Method callback;
//事件的名称,触发的是什么事件
private String trigger;
//事件触发的时间
private long time;
public Event(Object target, Method callback) {
this.target = target;
this.callback = callback;
}
public Event setSource(Object source) {
this.source = source;
return this;
}
public Event setTime(long time) {
this.time = time;
return this;
}
public Object getSource() {
return source;
}
public Event setTrigger(String trigger) {
this.trigger = trigger;
return this;
}
public long getTime() {
return time;
}
public Object getTarget() {
return target;
}
public Method getCallback() {
return callback;
}
@Override
public String toString() {
return "Event{" + "\n" +
"\tsource=" + source.getClass() + ",\n" +
"\ttarget=" + target.getClass() + ",\n" +
"\tcallback=" + callback + ",\n" +
"\ttrigger='" + trigger + "',\n" +
"\ttime=" + time + "'\n" +
'}';
}
}
/**
* 监听器,它就是观察者
*/
public class EventLisenter {
//JDK底层的Lisenter通常也是这样来设计的
protected Map<String,Event> events = new HashMap<String,Event>();
//事件名称和一个目标对象来触发事件
public void addLisenter(String eventType,Object target){
try {
this.addLisenter(
eventType,
target,
target.getClass().getMethod("on" + toUpperFirstCase(eventType),Event.class));
}catch (Exception e){
e.printStackTrace();
}
}
public void addLisenter(String eventType,Object target,Method callback){
//注册事件
events.put(eventType, new Event(target, callback));
}
//触发,只要有动作就触发
private void trigger(Event event) {
event.setSource(this);
event.setTime(System.currentTimeMillis());
try {
//发起回调
if(event.getCallback() != null){
//用反射调用它的回调函数
event.getCallback().invoke(event.getTarget(),event);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//事件名称触发
protected void trigger(String trigger){
if(!this.events.containsKey(trigger)){return;}
trigger(this.events.get(trigger).setTrigger(trigger));
}
//逻辑处理的私有方法,首字母大写
private String toUpperFirstCase(String str){
char[] chars = str.toCharArray();
chars[0] -= 32;
return String.valueOf(chars);
}
}
public class Keybord extends EventLisenter {
public void down(){
}
public void up(){
}
}
public interface MouseEventType {
//单击
String ON_CLICK = "click";
//双击
String ON_DOUBLE_CLICK = "doubleClick";
//弹起
String ON_UP = "up";
//按下
String ON_DOWN = "down";
//移动
String ON_MOVE = "move";
//滚动
String ON_WHEEL = "wheel";
//悬停
String ON_OVER = "over";
//失焦
String ON_BLUR = "blur";
//获焦
String ON_FOCUS = "focus";
}
public class Mouse extends EventLisenter {
public void click(){
System.out.println("调用单击方法");
this.trigger(MouseEventType.ON_CLICK);
}
public void doubleClick(){
System.out.println("调用双击方法");
this.trigger(MouseEventType.ON_DOUBLE_CLICK);
}
public void up(){
System.out.println("调用弹起方法");
this.trigger(MouseEventType.ON_UP);
}
public void down(){
System.out.println("调用按下方法");
this.trigger(MouseEventType.ON_DOWN);
}
public void move(){
System.out.println("调用移动方法");
this.trigger(MouseEventType.ON_MOVE);
}
public void wheel(){
System.out.println("调用滚动方法");
this.trigger(MouseEventType.ON_WHEEL);
}
public void over(){
System.out.println("调用悬停方法");
this.trigger(MouseEventType.ON_OVER);
}
public void blur(){
System.out.println("调用获焦方法");
this.trigger(MouseEventType.ON_BLUR);
}
public void focus(){
System.out.println("调用失焦方法");
this.trigger(MouseEventType.ON_FOCUS);
}
}
public class MouseEventCallback {
public void onClick(Event e){
System.out.println("===========触发鼠标单击事件==========" + "\n" + e);
}
public void onDoubleClick(Event e){
System.out.println("===========触发鼠标双击事件==========" + "\n" + e);
}
public void onUp(Event e){
System.out.println("===========触发鼠标弹起事件==========" + "\n" + e);
}
public void onDown(Event e){
System.out.println("===========触发鼠标按下事件==========" + "\n" + e);
}
public void onMove(Event e){
System.out.println("===========触发鼠标移动事件==========" + "\n" + e);
}
public void onWheel(Event e){
System.out.println("===========触发鼠标滚动事件==========" + "\n" + e);
}
public void onOver(Event e){
System.out.println("===========触发鼠标悬停事件==========" + "\n" + e);
}
public void onBlur(Event e){
System.out.println("===========触发鼠标失焦事件==========" + "\n" + e);
}
public void onFocus(Event e){
System.out.println("===========触发鼠标获焦事件==========" + "\n" + e);
}
}
public class MouseEventTest {
public static void main(String[] args) {
MouseEventCallback callback = new MouseEventCallback();
Mouse mouse = new Mouse();
//@谁? @回调方法
mouse.addLisenter(MouseEventType.ON_CLICK,callback);
mouse.addLisenter(MouseEventType.ON_FOCUS,callback);
mouse.click();
mouse.focus();
}
}