反射增加装饰者的普适性

反射增加装饰者的普适性_第1张图片

装饰模式

装饰模式在中国使用的那实在是多,中国的文化是中庸文化,说话或做事情都不能太直接,需要
有技巧的,比如说话吧,你要批评一个人,你不能一上来就说你这个做的不对,那个做的不对,你要先肯
定他的成绩,表扬一下优点,然后再指出瑕疵,指出错误的地方,最后再来个激励,你修改了这些缺点后
有那些好处,比如你能带更多的小兵,到个小头目等等,否则你一上来就是一顿批评,你瞅瞅看,肯定是
不服气,顶撞甚至是直接“此处不养爷,自有养爷处”开溜哇。


我们不说不开心的事情,今天举一个什么例子呢?就说说我上小学的的糗事吧。我上小学的时候学习
成绩非常的差,班级上 40 多个同学,我基本上都是在排名 45 名以后,按照老师给我的定义就是“不是读
书的料”,但是我老爸管的很严格,明知道我不是这块料,还是往赶鸭子上架,每次考试完毕我都是战战兢
兢的,“竹笋炒肉”是肯定少不了的,能少点就少点吧,肉可是自己的呀。四年级期末考试考完,学校出来
个很损的招儿(这招儿现在很流行的),打印出成绩单,要家长签字,然后才能上五年级,我那个恐惧呀,
不过也就是几秒钟的时间,玩起来什么都忘记了。


package com.the151suggestions.part7;

/**
 * Created by wanggs on 2017/7/24.
 * 装饰模式
 */
public class S1070 {
    public static void main(String[] args) {
        // 老爸开始看成绩单,这个成绩单可是最真实的,啥都没有动过,原装,看 Father 类:
        //成绩单拿过来
        SchoolReport sr = new FouthGradeSchoolReport();
        //看成绩单
        sr.report();
        //签名?休想

        System.out.println("*************************");

        //美化过的成绩单拿过来
        SchoolReport src = new SugarFouthGradeSchoolReport();
        src.report();
        src.sign("老鼠");


        //成绩单拿过来
        SchoolReport srr;
        sr = new FouthGradeSchoolReport(); //原装的成绩单
//加 了最高分说明的成绩单
        srr = new HighScoreDecorator(sr);
//又加了成绩排名的说明
        srr = new SortDecorator(srr);
//看成绩单
        srr.report();
//然后老爸,一看,很开心,就签名了
        srr.sign("老三"); //我叫小三,老爸当然叫老三

    }
}

/**
 * 成绩单抽象类
 */
abstract class SchoolReport {
    //成绩单的主要展示的就是你的成绩情况
    public abstract void report();

    //成绩单要家长签字,这个是最要命的
    public abstract void sign(String name);
}

/**
 * 四年级的成绩单,这个是我们学校第一次实施,以前没有干过
 * 这种“缺德”事。
 */
class FouthGradeSchoolReport extends SchoolReport {

    // 我的成绩单
    @Override
    public void report() {

        //成绩单的格式是这个样子的
        System.out.println("尊敬的XXX家长:");
        System.out.println(" ......");
        System.out.println(" 语文 62 数学65 体育 98 自然 63");
        System.out.println(" .......");
        System.out.println(" 家长签名: ");
    }


    public void sign(String name) {
        System.out.println("家长签名为: " + name);
    }
}

/**
 * 对这个成绩单进行美化
 * Sugar这个词太好了,名词是糖的意思,动词就是美化
 * 给你颗糖你还不美去
 */
class SugarFouthGradeSchoolReport extends FouthGradeSchoolReport {
    //首先要定义你要美化的方法,先给老爸说学校最高成绩
    private void reportHighScore() {
        System.out.println("这次考试语文最高是75,数学是78,自然是80");
    }

    //在老爸看完毕成绩单后,我再汇报学校的排名情况
    private void reportSort() {
        System.out.println("我是排名第38名...");
    }

    //由于汇报的内容已经发生变更,那所以要重写父类
    @Override
    public void report() {
        this.reportHighScore(); //先说最高成绩
        super.report(); //然后老爸看成绩单
        this.reportSort(); //然后告诉老爸学习学校排名
    }
}

/**
 * 老爸听我汇报最高成绩后,就直接乐开花了,直接签名了,后面的排名就没必要了,或者老爸要先听排名情况,
 * 那怎么办?继续扩展类?你能扩展多少个类?这还是一个比较简单的场景,一旦需要装饰的条件非常的多,比如
 * 20 个,你还通过继承来解决,你想想的子类有多少个?你是不是马上就要崩溃了!
 */

//装饰类,我要把我的成绩单装饰一下
//Decorator 抽象类的目的很简单,就是要让子类来对封装 SchoolReport 的子类,怎么封装?
abstract class Decorator extends SchoolReport {
    //首先我要知道是那个成绩单
    private SchoolReport sr;

    //构造函数,传递成绩单过来
    public Decorator(SchoolReport sr) {
        this.sr = sr;
    }

    //成绩单还是要被看到的
    public void report() {
        this.sr.report();
    }

    //看完毕还是要签名的
    public void sign(String name) {
        this.sr.sign(name);
    }
}

// 我要把我学校的最高成绩告诉老爸
class HighScoreDecorator extends Decorator {
    public HighScoreDecorator(SchoolReport sr) {
        super(sr);
    }

    //我要汇报最高成绩
    private void reportHighScore() {
        System.out.println("这次考试语文最高是75,数学是78,自然是80");
    }

    //最高成绩我要做老爸看成绩单前告诉他,否则等他一看,就抡起笤帚有揍我,我那还有机会说呀
    @Override
    public void report() {
        this.reportHighScore();
        super.report();
    }
}

//学校排名的情况汇报
class SortDecorator extends Decorator{
    public SortDecorator(SchoolReport sr) {
        super(sr);
    }
    //告诉老爸学校的排名情况
    private void reportSort(){
        System.out.println("我是排名第38名...");
    }
    //老爸看完成绩单后再告诉他,加强作用
    @Override
    public void report(){
        super.report();
        this.reportSort();
    }
}

反射增加装饰者的普适性

package com.the151suggestions.part7;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;

/**
 * Created by wanggs on 2017/7/24.
 * 使用反射增加装饰者的普适性
 * 让小老鼠更加强大
 * 此类代码是比较通用的装饰着模式, 只需定义被装饰的类级装饰类即可, 装饰行为由动态代理实现, 实现了对装饰类和被装饰类的解耦
 */
public class S107 {
    public static void main(String[] args) {
        Animal jetty = new Rat();
        // 为jetty增加飞行能力
        jetty = new DecorateAnimal(jetty,FlyFeature.class);

        // 增加挖地能力
        jetty = new DecorateAnimal(jetty,DigFeature.class);
        // 耍猫
        jetty.doStuff();

    }

}

interface Animal {
    public void doStuff();
}

// 老鼠
class Rat implements Animal {

    @Override
    public void doStuff() {
        System.out.println("Jetty will play Tom");
    }
}

// 定义某种功能
interface Feature {
    // 加载特性
    public void load();
}

// 飞行能力
class FlyFeature implements Feature {

    @Override
    public void load() {
        System.out.println("增加一双翅膀....");
    }
}

// 钻地能力
class DigFeature implements Feature {
    @Override
    public void load() {
        System.out.println("增加钻地能力....");
    }
}

// 包装类
class DecorateAnimal implements Animal {
    // 包装动物
    private Animal animal;
    // 使用哪一个包装器
    private Class clz;

    public DecorateAnimal(Animal animal, Class clz) {
        this.animal = animal;
        this.clz = clz;
    }

    @Override
    public void doStuff() {
        // 匿名
        InvocationHandler handler = new InvocationHandler() {
            // 包装具体行为
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object object = null;
                // 设置包装条件
                if (Modifier.isPublic(method.getModifiers())) {
                    object = method.invoke(clz.newInstance(), args);

                }
                animal.doStuff();
                return object;
            }
        };
// 当前类加载器
        ClassLoader classLoader = getClass().getClassLoader();
        // 动态代理,由Handler决定如何包装
        Feature proxy = (Feature) Proxy.newProxyInstance(classLoader, clz.getInterfaces(), handler);
        proxy.load();
    }
}

你可能感兴趣的:(反射增加装饰者的普适性)