eric-1001c

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            3 隨筆 :: 45 文章 :: 12 評論 :: 0 Trackbacks
          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          只要一個方法操作的是類而非接口,那么你就只能使用這個類及其子類。如果你想要將這個方法應用于不在此繼承結構中的某個類,那么你就會倒大霉了。接口可以在很大程序上放寬這種限制,因此它使得我們可以編寫可復用性更好的代碼
          首先看,通過類的繼承實現的一個程序
          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);

              }

          }

          這個例子很簡單,只是把字符串轉換為大寫,小寫和以空格拆分的字符串。值得注意的是負責轉換的類Upcase, Downcase和Splitter都是繼承于Processor的,而Processor是一個普通的類。咋一看是沒問題的,但是要想通過復用把以下的別的類似的程序就不方便了
          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;
              }

          }

          因為在Apply.process()方法在傳入的是Processor類,而Filter的創建者壓根不清楚它將要被用作Processor。也許你會認為通過繼承Process就把問題解決了,但是你會發現Filter.process和Process.process的方法簽名是不一樣的,那就是說Filter并沒有覆蓋Process的方法,這樣將會導致不安全性(Filter因繼承而多了一個不在設計范圍內的方法)。因此使得代碼復用就很難了,主要的原因是Apply.process()和Process之間的耦合太緊了。如果把Processor改為接口,這些限制就會變得松動了
          interface Processor {
              String name();
              Object process(Object input);
          }

          //把導出類的name方法抽取出來單獨設置一個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);
                  }

          }
          這種我們就可以通過實現接口而在復用的基礎上加入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);
                  }

          }
          上面的例子很好說明了,不用修改原程序(當然Filter還是要改的),可以直接通過復用接口Processor和Apply.process()。然后有的時候Filter并不是可以修改的,或者你得到的只是一個類庫,這個時候可以使用Adaptor設計模式
          //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);
                  }

          }
          在這種使用適配器的方式中,FilterAdapter的構造器接受你所擁有的接口Filter,然后生成具有你所需要的Processor接口的對象。在FilterAdapter中還使用了代理

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

          評論

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

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

          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);
          }
          }  回復  更多評論
            

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

          主站蜘蛛池模板: 余干县| 交城县| 玉龙| 东明县| 通道| 九江县| 武定县| 磐安县| 虞城县| 凤山市| 宽甸| 荥阳市| 平昌县| 台东市| 扎赉特旗| 东阳市| 封开县| 伊川县| 蕉岭县| 获嘉县| 建平县| 万载县| 石屏县| 龙陵县| 柳州市| 株洲县| 芮城县| 深水埗区| 甘德县| 吴川市| 普陀区| 民丰县| 安达市| 林西县| 从江县| 二连浩特市| 夹江县| 鹤庆县| 报价| 孝感市| 尼木县|