JAVA~~~i love you

2006年8月2日

面向对象设计之LSP

      前段时间完成我的毕业论文,是关于面向对象设计原则和设计模式的一些讨论,为此重读了Robert C.Martin的《Aglile Software Development Principles,Patterns and Pratices》这本著作,对面向对象设计有了一个新的认识,在这里和大家分享一下。
      《Agile》一书中提到一系列的面向对象设计原则,其中一条是叫作LSP---Liskov替换原则。LSP是Barbara Liskov在她1988年的论文中提出的,其内容是:子类必须能够完全替换掉它的父类。LSP是使OCP成立的条件之一(关于OCP在以后的文章会作讨论),二者都是面向对象的多态和抽象的基础。
      举个例子,当我们有一个Car这个类

public   class  Car {
    
    
public   void  run(){
        System.out.println(
" I am running " );
    }
    
    
public   void  stop(){
        System.out.println(
" I am stop " );
    }
}

现在,如果有一个类与Car类有关系,在面向对象中,类之间的关系就是组合和继承。当确定这个类为另外一个类的使用者、拥有者时就用组合,譬如Person类使用Car类。使用者的类有一个特征就是运行时多态放在它们之间是不管用的,譬如Person可能有一些eat、laugh等公共方法,如果Person是Car的子类,根据运行时多态就可以用Car来替换Person,Car就有得eat这个方法,显然是不合逻辑的。
    如果确定是有一种特殊的Car会飞的,除了run和stop之外还有一个fly的方法,现在就是使用继承的场合。

public class FlyingCar extends Car {

    
public void fly(){
        System.out.println(
"I am Fly");
    }
}

虽然使用了继承,但是确违反了LSP。因为Car中并没有fly这个方法,运行时多态便被破坏。为了获得多态性,将Car重构为抽象类,在其中添加一个抽象的fly方法,多态性便得以保存。但是这样做的话就说明所有Car的抽象都是会fly的,这显然是不合理。为此,应该去掉Car中的fly方法,Car就不是抽象类,再由Car这个抽象类派生出抽象的FlyingCar,里面包含fly的抽象方法。这样,FlyingCar抽象类和它的派生类就确保遵守了LSP了。
      还有一种做法,将fly方法抽象到一个Flyable接口中。FlyingCar在继承Car的同时实现Flyable接口,就是说,FlyingCar的上级父类就是Car和Flyable,按照LSP是完全可以覆盖父类的。
public interface Flyable {

    
void fly();
}

public class FlyingCar extends Car implements Flyable {

    
public void fly(){
        System.out.println(
"I am fly");
    }
}

使用运行时多态时要获得fly方法必须转型为Flyable接口
public class CarMain {

    
public static void main(String[] args) {
        Car car
=new FlyingCar();
        car.run();
        car.stop();
        ((Flyable)car).fly();
    }
}

LSP是指导使用继承的准则。继承肯定是子类添加父类所不具有的新方法的,此时若忽略LSP,多态性便会在设计中消失。所以当使用继承时,为了保证多态性,就需要遵守LSP多做一些工作了。

posted @ 2006-08-03 00:28 it民工 阅读(765) | 评论 (1)编辑 收藏

Common IO学习

         一直都在看BlogJava上的文章,从众多的Java爱好者那里学到了不少的知识,但是却没有在自己blog上发过文章。渐渐地,觉得这种只会索取不作贡献的行为是不行的,请原谅我有点害羞吧,哈哈。所以从现在开始我会陆续地在blog上面发表关于Java、软件开发的文章,希望大家能多多指教。
         闲话说到这,近来在阅读一本关于Jakarta Common的书,就写一下关于Jakarta Common这一系列工具的文章吧。什么是Jakarta Common呢?它是一系列Apache的子项目,包括Collections、XML、JavaBean、IO等一系列增强Java的工具类,在许多Apache的项目中都可以看到它们的身影,如Struts。现在介绍的是Common IO,这个包主要使IO与网络之间编程更加方便,编码更加清晰。
         其中CopyUtils和IOUtils提供一系列静态方法使到stream和Reader/Writer和String之间的转变更加容易希望从一个InputStream将读取的流转变为FileWriter写入一个文件,只需要使用CopyUtils的copy方法,这个方法有多个重载版本,这里接受一个InputStream的对象和一个FileWriter的对象。
    public void performCopying(){
        Writer writer
=null;
        InputStream inputStream
=null;
        
try {
            writer
=new FileWriter("test.dat");
            inputStream
=getClass().getResourceAsStream("./test.resource");
            CopyUtils.copy(inputStream,writer);
        } 
catch (IOException e) {
            e.printStackTrace();
        }
finally{
            IOUtils.closeQuietly(writer);
            IOUtils.closeQuietly(inputStream);
        }
    }

最后很方便的是,使用IOUtils的closeQuietly静态方法就可以方便地关闭资源。同样地,从一个网络上的地址上获得网页内容到字符串也是非常地直观。
    public void urlToString(){
        URL url
=null;
        InputStream inputStream
=null;
        
        
try {
            url
=new URL("http://www.21cn.com");
            inputStream
=url.openStream();
            String contents
=IOUtils.toString(inputStream);
            System.out.println(contents);
        } 
catch (MalformedURLException e) {
            e.printStackTrace();
        } 
catch (IOException e) {
            e.printStackTrace();
        }
    }

使用IOUtils的toString的一个重载版本就可以方便地做到上述功能。Common IO还有许多有用的功能,在以后的文章会继续探讨。

posted @ 2006-08-02 22:11 it民工 阅读(1993) | 评论 (0)编辑 收藏

<2006年8月>
303112345
6789101112
13141516171819
20212223242526
272829303112
3456789

导航

统计

常用链接

留言簿(1)

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜