装饰者设计模式

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
/*
装饰者设计模式:增强一个类的功能,而且还可以让这些装饰类互相装饰。

装饰者设计模式的步骤:
    1. 在装饰类的内部维护一个被装饰类的引用。
    2. 让装饰类有一个共同的父类或者是父接口。

需求1: 编写一个类拓展BufferedReader的功能, 增强readLine方法返回 的字符串带有行号。

 需求2:编写一个类拓展BufferedReader的功能, 增强readLine方法返回 的字符串带有分号。

 需求3: 编写一个类拓展BufferedReader的功能, 增强readLine方法返回 的字符串带有双引号。

 需求4: 编写一个类拓展BufferedReader的功能, 增强readLine方法返回 的字符串带有行号+ 分号。

 需求5: 编写一个类拓展BufferedReader的功能, 增强readLine方法返回 的字符串带有分号+ 双引号。

 需求6: 编写一个类拓展BufferedReader的功能, 增强readLine方法返回 的字符串带有双引号+ 行号。

 需求7: 编写一个类拓展BufferedReader的功能, 增强readLine方法返回 的字符串带有行号+ 分号+双引号。

继承实现的增强类和修饰模式实现的增强类有何区别?

    继承实现的增强类:
        优点:代码结构清晰,而且实现简单.
        缺点:对于每一个的需要增强的类都要创建具体的子类来帮助其增强,这样会导致继承体系过于庞大。

修饰模式实现的增强类:
        优点:内部可以通过多态技术对多个需要增强的类进行增强, 可以是这些装饰类达到互相装饰的效果。使用比较灵活。

        缺点:需要内部通过多态技术维护需要被增强的类的实例。进而使得代码稍微复杂。

*/
import java.io.IOException;

//带行号的缓冲输入字符流
class BufferedLineNum2  extends BufferedReader{  

    //在内部维护一个被装饰类的引用。
    BufferedReader bufferedReader;

    int count = 1;

    public BufferedLineNum2(BufferedReader bufferedReader){
        super(bufferedReader);// 注意: 该语句没有任何的作用,只不过是为了让代码不报错。
        this.bufferedReader = bufferedReader;
    }

    public String readLine() throws IOException{
        String line = bufferedReader.readLine();
        if(line==null){
            return null;
        }
        line = count+" "+line;
        count++;
        return line;
    }
} 

//带分号缓冲输入字符流
class BufferedSemi2 extends BufferedReader{  //为什么要继承?  是为了让这些装饰类的对象可以作为参数进行传递,达到互相装饰 的效果。

    //在内部维护一个被装饰类的引用。
    BufferedReader bufferedReader;

    public BufferedSemi2(BufferedReader bufferedReader){ // new BuffereLineNum();
        super(bufferedReader);// 注意: 该语句没有任何的作用,只不过是为了让代码不报错。
        this.bufferedReader = bufferedReader;
    }

    public String readLine() throws IOException{
        String line = bufferedReader.readLine();  //如果这里的ReadLine方法是调用了buffereLineNum的readLine方法,问题马上解决。
        if(line==null){
            return null;
        }
        line = line +";";
        return line;
    }

}

//缓冲类带双引号
class BufferedQuto2 extends BufferedReader{

    //在内部维护一个被装饰的类
    BufferedReader bufferedReader;

    public BufferedQuto2(BufferedReader bufferedReader){  //new  BufferedSemi2();
        super(bufferedReader) ; //只是为了让代码不报错..
        this.bufferedReader = bufferedReader;
    }

    public String readLine() throws IOException{
        String line = bufferedReader.readLine();  //如果这里的ReadLine方法是调用了buffereLineNum的readLine方法,问题马上解决。
        if(line==null){
            return null;
        }
        line = "\""+line +"\"";
        return line;
    }

}

public class Demo2 {

    public static void main(String[] args) throws IOException {
        File file = new File("F:\\Demo1.java");
        FileReader fileReader = new FileReader(file);
        //建立缓冲输入字符流
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        //建立带行号的缓冲输入字符流
        BufferedLineNum2 bufferedLineNum = new BufferedLineNum2(bufferedReader);

        //带分号的缓冲输入字符流
        BufferedSemi2 bufferedSemi2 = new BufferedSemi2(bufferedLineNum);

        //带双引号的缓冲输入字符流
        BufferedQuto2 bufferedQuto2 = new  BufferedQuto2(bufferedSemi2);

        String line = null;
        while((line = bufferedQuto2.readLine())!=null){
            System.out.println(line);
        }

    }

}
/*练习:
    一家三口每个人都会工作,儿子的工作就是画画,母亲的工作就是在儿子的基础上做一个增强,不单止可以画画,还可以上涂料。
    爸爸的工作就是在妈妈基础上做了增强,就是上画框。
*/

interface Work{

    public void work();
}

class Son implements Work{

    @Override
    public void work() {
        System.out.println("画画...");
    }
}

class Mather implements Work{

    //需要被增强的类。
    Work worker;

    public Mather(Work worker){
        this.worker = worker;
    }

    @Override
    public void work() {
        worker.work();
        System.out.println("给画上颜色..");
    }
}

class Father implements Work{

    //需要被增强的类的引用
    Work worker;

    public Father(Work worker){
        this.worker = worker;
    }

    @Override
    public void work() {
        worker.work();
        System.out.println("上画框...");
    }

}

public class Demo3 {

    public static void main(String[] args) {
        Son s = new Son();
//        s.work();
        Mather m = new Mather(s);
//        m.work();
        Father f = new Father(s);
        f.work();

    }
}
时间: 2024-10-07 06:12:33

装饰者设计模式的相关文章

(java)从零开始之--装饰者设计模式

装饰者设计模式:简单定义:增强一个类的功能,而且还可以让这些装饰类互相装饰. 应用场景:当要在某个功能的基础上扩充功能,并且扩充的功能具有大量排列组合,通过继承关系会衍生出大量子类,这时候用装饰者模式来解决. 装饰者设计模式的步骤: 1. 在装饰类的内部维护一个被装饰类的引用. 2. 让装饰类有一个共同的父类或者是父接口. 例如:人有一种行为叫“吃水果”,其中水果有4种:苹果.香蕉.鸭梨.橘子现在有需求如下: A类人行为:吃苹果 B类人行为:先吃苹果,再吃香蕉 C类人行为:先吃香蕉,再吃苹果 D

设计模式--装饰者设计模式(Decorator)

装饰者模式又叫包装模式. 通过另一个对象来扩展自己的行为,在不破坏类的封装的情况下,实现松耦合,易扩展的效果. 抽象组件角色: 一个抽象接口,是被装饰类和装饰类的父接口可以给这些对象动态地添加职责. 具体组件角色:为抽象组件的实现类,是定义了一个具体的对象,也可以给这个对象添加一些职责. 抽象装饰角色:包含一个组件的引用,并定义了与抽象组件一致的接口,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator存在的. 具体装饰角色

【ThinkingInJava】42、装饰器设计模式

/** * 书本:<Thinking In Java> * 功能:装饰器设计模式 * 装饰器模式使用分层对象来动态透明的向单个对象添加责任.装饰器指定包装在最初的对象周围的所有对象都具有相同的基本接口 * 某些事物是可装饰的,可以通过将其他类包装在这个可装饰对象的四周,来将功能分层. * 装饰器是通过使用组合和形式化结构(可装饰物/装饰器层次结构)来实现的,而混型是基于继承的 * 文件:Decoration.java * 时间:2015年4月21日10:18:43 * 作者:cutter_po

装饰器设计模式初探(Java实现)

本篇随笔主要介绍用Java实现简单的装饰器设计模式: 先来看一下装饰器设计模式的类图:  从图中可以看到,我们可以装饰Component接口的任何实现类,而这些实现类也包括了装饰器本身,装饰器本身也可以再被装饰. 下面是用Java实现的简单的装饰器设计模式,提供的是从基本的加入咖啡入手,可以继续加入牛奶,巧克力,糖的装饰器系统. 1 interface Component { 2 void method(); 3 } 4 class Coffee implements Component { 5

用过滤器和装饰者设计模式(静态代理)解决getParameter乱码问题

post的乱码问题比较好解决,这里主要是对get请求的乱码做处理 解决思路:增强request对象的getParameter方法,使之 getParameter  直接获取到的就是解决乱码后的数据 有四种方式, 1.继承 :(下下策) ①明确知道全类名 可以打印request实现类,可以知道实现类的全类名 ②就是可以在子类中 new 父类 你能确定request实现类,一定可以new么? 确定自己写出的是通用方法.tomcat,weblogic,jboss...... 缺点: ①很难实现,几乎没

装饰器设计模式

通俗的讲装饰器就是在不改变对象结构的前提下,扩充对象的功能. 下面以effective java中例题 问题  我想扩充Hash<set>功能,使得能够统计添加过元素的个数? 或许你可能会自定义一个类通过继承扩展,从而实现计数功能,代码如下: package com.effectJava.Chapter2; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; public class I

Java学习总结(8)—内存流,打印流,对象流,RandomAccessFile,装饰者设计模式

一.内存流 内存流主要用来操作内存 BytearrayInputStream和ByteArrayOutputStream输入和输出可以把文件作为数据源,也可以把内存作为数据源 (1)ByteArrayInputStream主要完成将内容从内存读入到程序中,而ByteArrayOutputStream的主要功能是是将数据写入到内存中 (2)注意:因为这两个流没有使用系统资源,所以不用关闭,也不需要抛出异常 内存操作示意图 (1)从程序中读:程序<-ByteArrayInputStream<-内存

设计模式(5)------装饰者设计模式(IO流的应用)

一:io流中的装饰者设计模式 java.io包内的类太多了,简直是--"排山倒海".你第一次(还有第二次和第三次)看到这些API发出"哇"的惊叹时,放心,你不是唯一受到惊吓的人.现在,你已经知道装饰者模式,这些I/O的相关类对你来说应该更有意义了,因为其中许多类都是装饰者.下面是一个典型的对象集合,用装饰者来将功能结合起来,以读取文件数据: 我们来看一下下面的这张类图 你可以发现,和星巴兹的设计相比,java.io其实没有多大的差异.我们把java.ioAAPI范围

设计模式(4)------装饰者设计模式

一,需求 现在在星巴克咖啡店,有4中咖啡,有无数种的配料,怎样算出一种咖啡随机加配料的价格,加配料肯能是一种,也可能是多种,而且也有可能是重复的. 如图: 假如现在根据每一个不同的配料新增一个类的话会是怎么样的呢,看图. 是不是要爆炸了呢. 那怎么解决这个问题呢. 好了,现在我们来修改一下这个设计好吧!就来试试看.先从Beverage基类下手,加上实例变量代表是否加上调料(牛奶.豆浆.摩卡.奶泡--) 上面的修复可能出现什么问题呢?调料价钱的改变会使我们更改现有代码. 一旦出现新的调料,我们就需