A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© pthuakai 中级黑马   /  2013-5-7 09:46  /  2022 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 pthuakai 于 2013-5-8 09:17 编辑

装饰类设计模式中,毕老师给了如下代码。但是我还是对装饰类不太明白,求高手指点。我感觉这和普通类调用没什么区别啊
package day19;
class Person
{
public void chifan()
{
  System.out.println("eat");
  
}
}
class SuperPerson
{
private Person p;
SuperPerson(Person p)
{
  this.p=p;
}
public void superChifan()
{
  System.out.println("drink");
  p.chifan();
  System.out.println("bread");
  System.out.println("somk");
  
}
}
public class PersonDemo {
public static void main(String[] args) {
  // TODO Auto-generated method stub
  Person p=new Person();
  SuperPerson sp=new SuperPerson(p);
  sp.superChifan();
  
}
}

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

4 个回复

倒序浏览
装饰类与普通调用的区别是将需要被装饰的类对象做为参数传递给装饰类的构造函数,然后再增强的方法中直接调用被装饰类的方法,而不需要创建被装饰类的对象。
回复 使用道具 举报
本帖最后由 Jacky_Chen1990 于 2013-5-7 10:25 编辑

你把装饰和继承进行对比,思考一下会比较好 下面代码有详细注释

区别
a) 继承相对装饰来说,体系臃肿,更加复杂,而且意图不明确。
b) 装饰类降低了类与类之间的关系,增强了意图和功能型需求。

什么时候使用
如果要增强功能的话,只需要把 被装饰的类的对象当成装饰类的构造函数的参数传递进来,写相应的增强的方法即可,这个方法如果错误也不会影响原来的方法的使用。
如果不是增强功能,而又其他的目的或者说需要用到父类的方法,那么就采用继承就可以了

代码如下:用的就是毕老师上课的代码。

package com.itheima;

/*
* 装饰设计模式:
* 当想要对已有的对象进行功能增强时,
* 可以定义类,将已有对象传入,基于已有对象的功能,并提供加强功能
* 那么自定义的该类就称为装饰类
*
* 装饰类通常会通过构造方法接收被装饰的对象。
* 并基于被装饰的对象的功能,提供更强的功能。
*/
public class PersonDemo {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                Person p = new Person();
               
                p.chifan();
        }

}

//原来的类
class Person {
        public void chifan() {
                System.out.println("吃饭");
        }
}

//增强了的类,就是装饰类
class SuperPerson {
        private Person p = null;
        
        SuperPerson(Person p){
                this.p = p;
        }
        
        public void superChifan() {
                System.out.println("开胃酒");
                p.chifan();
                System.out.println("吃甜点");
        }
}

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
1、简述:当想对已有对象进行功能增强是,可定义类:将已有对象传入,基于已有对象的功能,并提供加强功能,那么自定义的该类称之为装饰类。即对原有类进行了优化。
装饰设计模式:
当想要对已有的对象进行功能增强时,
可以定义一个类,将已有对象传入,基于已有的功能,并提供加强功能
那么自定义的该类称为装饰类
装饰类通常会通过构造方法接受被装饰的对象
并基于被装饰的对象的功能,提供更详细的功能。
2、特点:装饰类通常都会通过构造方法接收被装饰的对象,并基于被装饰的对i型那个的功能提供更强的功能。
3、装饰和继承的区别:
1)装饰模式比继承要灵活,通过避免了继承体系的臃肿,且降低了类与类间的关系。
2)装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强的功能,所以装饰类和被装饰的类通常都是属于一个体系。
3)从继承结构转为组合结构。
注:在定义类的时候,不要以继承为主;可通过装饰设计模式进行增强类功能。灵活性较强,当装饰类中的功能不适合,可再使用被装饰类的功能。
        要继承相应的父类,就需要将所有的抽象方法实现,或交给子类实现。其中毕老师写的MyBufferedReader的例子就是最好的装饰设计模式的例子,就是  对BufferedReader的增强。
  1. /*
  2. 明白了BufferedReader类中特有方法readLine的原理后,
  3. 可以自定义一个类中包含一个功能和readline一致的方法
  4. 来模拟一下BufferedReader
  5. */
  6. import java.io.*;

  7. class MyBufferedReader extends Reader
  8. {
  9.   
  10.   //装饰设计模式
  11.    private Reader r=null;
  12.    
  13.    MyBufferedReader(Reader r)
  14.    {
  15.       this.r=r;
  16.    }
  17.    //可以一次读一行数据的方法
  18.    public String myReadLine() throws IOException
  19.    {
  20.      //定义一个临时容器,员BufferedReader封装的是字符数组
  21.          //为了演示方便,定义一个StringBulilder容器,因为最终还是要将数据变成字符串。
  22.          StringBuilder sb=new StringBuilder();
  23.          int ch=0;
  24.          while((ch=r.read())!=-1)
  25.          {
  26.            if(ch=='\r')
  27.            continue;
  28.            if(ch=='\n')
  29.                 return sb.toString();
  30.            else
  31.            sb.append((char)ch);
  32.          }
  33.          //如果没有遇到\n,sb中而且有数据的话也要返回
  34.           if(sb.length()!=0)
  35.         return sb.toString();
  36.          return null;
  37.    }
  38.   /*
  39.   覆盖类中的抽象方法
  40.   */
  41.   public int read(char[] cbuf,int off,int len)throws IOException
  42.   {
  43.     return r.read(cbuf,off,len);
  44.   }
  45.   
  46.   public void close() throws IOException
  47.   {
  48.       r.close();
  49.   }
  50.   
  51.   public void myClose() throws IOException
  52.   {
  53.       r.close();
  54.   }
  55. }



  56. class MyBufferedReaderDemo
  57. {
  58.    public static void main(String[] args) throws IOException
  59.    {
  60.       FileReader fr=new FileReader("buf.txt");
  61.           
  62.           MyBufferedReader myBuf=new MyBufferedReader(fr);
  63.    
  64.       String line=null;
  65.           
  66.           while((line=myBuf.myReadLine())!=null)
  67.           {
  68.             System.out.println(line);
  69.           }
  70.           
  71.       myBuf.myClose();
  72.    }
  73.    
  74. }
复制代码

点评

其实不用说这么全面的,简单扼要的回答就可以了,不过你回答的很认真,不错  发表于 2013-5-7 21:29

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
谢谢高手指点
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马