<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    eric-1001c

      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      3 隨筆 :: 45 文章 :: 12 評(píng)論 :: 0 Trackbacks
    只要一個(gè)方法操作的是類而非接口,那么你就只能使用這個(gè)類及其子類。如果你想要將這個(gè)方法應(yīng)用于不在此繼承結(jié)構(gòu)中的某個(gè)類,那么你就會(huì)倒大霉了。接口可以在很大程序上放寬這種限制,因此它使得我們可以編寫(xiě)可復(fù)用性更好的代碼
    首先看,通過(guò)類的繼承實(shí)現(xiàn)的一個(gè)程序
    class Processor{
        
    public String name(){
            
    return getClass().getSimpleName();
        }

        Object process(Object input)
    {
            
    return input;
        }

    }

    class Upcase extends Processor{
        String process(Object input)
    {
            
    return ((String)input).toUpperCase();
        }

    }

    class Downcase extends Processor{
        String process (Object input)
    {
            
    return ((String)input).toLowerCase();
        }

    }

    class Splitter extends Processor{
        String process(Object input)
    {
            
    return Arrays.toString(((String)input).split(" "));
        }

    }


    public class Apply {
        
    public static String s = "Disagredment with beliefs is by definition incorrect";
        
    public static void process(Processor p, Object s){
            System.out.println(
    "Using Processor "+ p.name());
            System.out.println(p.process(s));
        }

        
    public static void main(String[] args) {
            process(
    new Upcase(),s);
            process(
    new Downcase(),s);
            process(
    new Splitter(),s);

        }

    }

    這個(gè)例子很簡(jiǎn)單,只是把字符串轉(zhuǎn)換為大寫(xiě),小寫(xiě)和以空格拆分的字符串。值得注意的是負(fù)責(zé)轉(zhuǎn)換的類Upcase, Downcase和Splitter都是繼承于Processor的,而Processor是一個(gè)普通的類。咋一看是沒(méi)問(wèn)題的,但是要想通過(guò)復(fù)用把以下的別的類似的程序就不方便了
    class Waveform{
        
    private static long counter;
        
    private final long id = counter++;
        
    public String toString(){
            
    return "Waveform" + id;
        }

    }

    class Filter{
        
    public String name(){
            
    return getClass().getSimpleName();
        }

        
    public Waveform process(Waveform input){
            
    return input;
        }

    }

    class LowPass extends Filter{
        
    double cutoff;
        
    public LowPass(double cutoff){
            
    this.cutoff = cutoff;
        }

        @Override
        
    public Waveform process (Waveform input){
            
    return input;
        }

    }

    class HighPass extends Filter{
        
    double cutoff;
        
    public HighPass(double cutoff){
            
    this.cutoff = cutoff;
        }

        
    public Waveform process(Waveform input){
            
    return input;
        }

    }

    class BandPass extends Filter{
        
    double lowCutoff,highCutoff;
        
    public BandPass(double lowCut, double highCut){
            lowCutoff 
    = lowCut;
            highCutoff 
    = highCut;
        }

    }

    因?yàn)樵贏pply.process()方法在傳入的是Processor類,而Filter的創(chuàng)建者壓根不清楚它將要被用作Processor。也許你會(huì)認(rèn)為通過(guò)繼承Process就把問(wèn)題解決了,但是你會(huì)發(fā)現(xiàn)Filter.process和Process.process的方法簽名是不一樣的,那就是說(shuō)Filter并沒(méi)有覆蓋Process的方法,這樣將會(huì)導(dǎo)致不安全性(Filter因繼承而多了一個(gè)不在設(shè)計(jì)范圍內(nèi)的方法)。因此使得代碼復(fù)用就很難了,主要的原因是Apply.process()和Process之間的耦合太緊了。如果把Processor改為接口,這些限制就會(huì)變得松動(dòng)了
    interface Processor {
        String name();
        Object process(Object input);
    }

    //把導(dǎo)出類的name方法抽取出來(lái)單獨(dú)設(shè)置一個(gè)abstract類
    abstract class StringProcessor implements Processor{
        
    public String name(){
            
    return getClass().getSimpleName();
        }

        
    public abstract String process(Object input);
    }

    class Upcase extends StringProcessor {
        @Override
        
    public String process(Object input) {
            
    return ((String)input).toUpperCase();
        }

    }

    class Splitter extends StringProcessor{
        @Override
        
    public String process(Object input) {
            
    return Arrays.toString(((String)input).split(" "));
        }

    }

    class Downcase extends StringProcessor {
        @Override
        
    public String process(Object input) {
            
    return ((String)input).toLowerCase();
        }

    }

    public class Apply {
        
    public static String s = "Disagredment with beliefs is by definition incorrect";
        
    public static void process(Processor p, Object s){
            System.out.println(
    "Using Processor "+ p.name());
            System.out.println(p.process(s));
        }

            
        
    public static void main(String[] args) {
                process(
    new Upcase(), s);
                process(
    new Downcase(),s);
                process(
    new Splitter(),s);
            }

    }
    這種我們就可以通過(guò)實(shí)現(xiàn)接口而在復(fù)用的基礎(chǔ)上加入Filter了
    abstract class Filter implements Processor {
        
    public String name() {
            
    return getClass().getSimpleName();
        }


        
    public abstract Waveform process(Object input);
    }

    class BandPass extends Filter{
        
    double lowCutoff,highCutoff;
        
    public BandPass(double lowCut, double highCut){
            lowCutoff 
    = lowCut;
            highCutoff 
    = highCut;
        }

        @Override
        
    public Waveform process(Object input) {
            
    return (Waveform) input;
        }

    }

    class HighPass extends Filter{
        
    double cutoff;
        
    public HighPass(double cutoff){
            
    this.cutoff = cutoff;
        }

        @Override
        
    public Waveform process(Object input) {
            
    return (Waveform) input;
        }

    }

    class LowPass extends Filter{
        
    double cutoff;
        
    public LowPass(double cutoff){
            
    this.cutoff = cutoff;
        }

        @Override
        
    public Waveform process (Object input){
            
    return (Waveform) input;
        }

    }

    public class Apply {
        
    public static String s = "Disagredment with beliefs is by definition incorrect";
        
    public static void process(Processor p, Object s){
            System.out.println(
    "Using Processor "+ p.name());
            System.out.println(p.process(s));
        }

            
        
    public static void main(String[] args) {
                
    //process(new Upcase(), s);
                
    //process(new Downcase(),s);
                
    //process(new Splitter(),s);
                
                Waveform w 
    = new Waveform();
                process(
    new LowPass(1.0),w);
                process(
    new HighPass(3.0),w);
                process(
    new BandPass(1.0,2.0),w);
            }

    }
    上面的例子很好說(shuō)明了,不用修改原程序(當(dāng)然Filter還是要改的),可以直接通過(guò)復(fù)用接口Processor和Apply.process()。然后有的時(shí)候Filter并不是可以修改的,或者你得到的只是一個(gè)類庫(kù),這個(gè)時(shí)候可以使用Adaptor設(shè)計(jì)模式
    //Filter不能修改
    class Filter{
        
    public String name(){
            
    return getClass().getSimpleName();
        }

    //    @Override
        public Waveform process(Waveform input){
            
    return input;
        }

    }

    //Filter的Adapter
    class FilterAdapter implements Processor {
        Filter filter;
        
    public FilterAdapter (Filter filter){
            
    this.filter = filter;
        }

        
    public String name() {
            
    return filter.name();
        }

        
    public Waveform process(Object input) {
            
    return filter.process((Waveform) input);
        }

    }
    public class Apply {
        
    public static String s = "Disagredment with beliefs is by definition incorrect";
        
    public static void process(Processor p, Object s){
            System.out.println(
    "Using Processor "+ p.name());
            System.out.println(p.process(s));
        }

            
        
    public static void main(String[] args) {        
                Waveform w 
    = new Waveform();        
                process(
    new FilterAdapter(new chapter9.LowPass(1.0)),w);
                process(
    new FilterAdapter(new chapter9.HighPass(3.0)),w);
                process(
    new FilterAdapter(new chapter9.BandPass(1.0,2.0)),w);
            }

    }
    在這種使用適配器的方式中,F(xiàn)ilterAdapter的構(gòu)造器接受你所擁有的接口Filter,然后生成具有你所需要的Processor接口的對(duì)象。在FilterAdapter中還使用了代理

    posted on 2007-07-12 19:23 Eric-1001c 閱讀(2544) 評(píng)論(3)  編輯  收藏 所屬分類: ThinkingInJava

    評(píng)論

    # re: 接口之完全解耦 2009-02-01 09:46 holmes
    thinking in java原文+源代碼  回復(fù)  更多評(píng)論
      

    # re: 接口之完全解耦[未登錄](méi) 2013-06-02 19:39 王杰
    一直以來(lái) 我的java基礎(chǔ)不是很好 最近在學(xué)習(xí)java基礎(chǔ) 看到繼承和接口這塊 令我實(shí)在不解的是我為什么在這個(gè)例子中要用interface ,下面這樣寫(xiě)不行嗎??好像不用接口 thinking in java中也是這么講的 我實(shí)在不解

    class FilterConver extends Processor{
    Filter filter;
    public FilterConver(Filter filter) {
    this.filter = filter;
    }
    @Override
    Waveform process(Object input) {
    // TODO Auto-generated method stub
    return filter.process((Waveform)input);
    }
    }  回復(fù)  更多評(píng)論
      

    # re: 接口之完全解耦[未登錄](méi) 2013-06-02 19:40 王杰
    如果可以解釋下直接QQ我吧 120482338 多謝哈   回復(fù)  更多評(píng)論
      


    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 日韩高清免费在线观看| 国产亚洲精品岁国产微拍精品| 亚洲AV无码一区二区三区DV | 亚洲6080yy久久无码产自国产| 日韩精品无码一区二区三区免费| 亚洲第一页日韩专区| 国产精品久久亚洲不卡动漫| 东北美女野外bbwbbw免费| 国产精品极品美女免费观看| 91亚洲性爱在线视频| 一区二区三区无码视频免费福利 | 亚洲黄色在线播放| 久久久久久久久久免免费精品| 久久久久国产精品免费免费搜索| 久久久久亚洲AV片无码| 一区二区三区视频免费观看| 日本免费无遮挡吸乳视频电影| 亚洲伊人色一综合网| 青青青国产手机频在线免费观看| 亚洲精品成人区在线观看| 国产成人人综合亚洲欧美丁香花 | 妞干网在线免费观看| 免费国产污网站在线观看15| 亚洲精品无码久久久| 亚洲heyzo专区无码综合| 男人的好免费观看在线视频| 亚洲无人区视频大全| 伊人久久免费视频| 精品国产_亚洲人成在线高清| 一级毛片高清免费播放| 免费国产高清视频| 最新亚洲人成网站在线观看| 成年性生交大片免费看| 亚洲国产综合精品| 曰批全过程免费视频播放网站 | 拍拍拍无挡视频免费观看1000| 亚洲精品第一国产综合精品99| 国产亚洲综合视频| 免费jjzz在在线播放国产| 麻豆亚洲AV成人无码久久精品 | 51午夜精品免费视频|