4、接口隔离原则: ISP(Interface Segregation Principle)  客户端不应该依赖它不需要的接口,或者说类的依赖的关系应该建立在最小的接口上。举个例子,直接上代码:

 1 interface I {

 2     public void method1();

 3     public void method2();

 4     public void method3();

 5     public void method4();

 6     public void method5();

 7 }

 8 

 9 class A{

     public void depend1(I i){

         i.method1();

     }

     public void depend2(I i){

         i.method2();

     }

     public void depend3(I i){

         i.method3();

     }

 }

 

 class B implements I{

     public void method1() {

         System.out.println("类B实现接口I的方法1");

     }

     public void method2() {

         System.out.println("类B实现接口I的方法2");

     }

     public void method3() {

         System.out.println("类B实现接口I的方法3");

     }

     //对于类B来说,method4和method5不是必需的,但是由于接口A中有这两个方法,

     //所以在实现过程中即使这两个方法的方法体为空,也要将这两个没有作用的方法进行实现。

     public void method4() {}

     public void method5() {}

 }

 

 class C{

     public void depend1(I i){

         i.method1();

     }

     public void depend2(I i){

         i.method4();

     }

     public void depend3(I i){

         i.method5();

     }

 }

 

 class D implements I{

     public void method1() {

         System.out.println("类D实现接口I的方法1");

     }

     //对于类D来说,method2和method3不是必需的,但是由于接口A中有这两个方法,

     //所以在实现过程中即使这两个方法的方法体为空,也要将这两个没有作用的方法进行实现。

     public void method2() {}

     public void method3() {}

 

     public void method4() {

         System.out.println("类D实现接口I的方法4");

     }

     public void method5() {

         System.out.println("类D实现接口I的方法5");

     }

 }

 

 public class Client{

     public static void main(String[] args){

         A a = new A();

         a.depend1(new B());

         a.depend2(new B());

         a.depend3(new B());

         

         C c = new C();

         c.depend1(new D());

         c.depend2(new D());

         c.depend3(new D());

     }

  相信大家也看出来了接口I太过臃肿了,实际开发中我们应该尽可能的避免这种现象出现。接口定义尽量细化。针对上面的问题,我们可以采用接口隔离来进行解决接口臃肿的问题。

 改造后代码:

 1 interface I1 {
 2     public void method1();
 3 }
 4 
 5 interface I2 {
 6     public void method2();
 7     public void method3();
 8 }
 9 
 interface I3 {
     public void method4();
     public void method5();
 }
 
 class A{
     public void depend1(I1 i){
         i.method1();
     }
     public void depend2(I2 i){
         i.method2();
     }
     public void depend3(I2 i){
         i.method3();
     }
 }
 
 class B implements I1, I2{
     public void method1() {
         System.out.println("类B实现接口I1的方法1");
     }
     public void method2() {
         System.out.println("类B实现接口I2的方法2");
     }
     public void method3() {
         System.out.println("类B实现接口I2的方法3");
     }
 }
 
 class C{
     public void depend1(I1 i){
         i.method1();
     }
     public void depend2(I3 i){
         i.method4();
     }
     public void depend3(I3 i){
         i.method5();
     }
 }
 
 class D implements I1, I3{
     public void method1() {
         System.out.println("类D实现接口I1的方法1");
     }
     public void method4() {
         System.out.println("类D实现接口I3的方法4");
     }
     public void method5() {
         System.out.println("类D实现接口I3的方法5");
     }

61 }

 将I接口细化为I1,I2,I3,这样在对这三个接口进行实现的时候,就不会出现多余的方法去实现而不进行任何操作的现象。注意:在对接口进行细化的时候,我们要求做到尽量和依赖类的业务保持一致。我的理解是,尽量不要违背单一职责原则。虽然与单一职责原则相似,但与单一职责不同的是,单一职责注重职责,而接口隔离原则更注重接口的依赖隔离。其次单一职责原则更注重的是约束类,然后再是接口和方法,接口隔离更注重约束接口,对程序架构的构建。

采用接口隔离原则注意几点:

1.接口尽量小,但是要有限度,过度小会造成接口繁多。

2.为依赖的类定制服务,不把依赖类不需要的方法暴露出来。

3.提高内聚,不要过多的与外交互。

5、迪米特法则 :LOD(Law Of  Demeter ) 一个类应该对自己需要耦合或者调用的类知道的最少,被调用的类内部是怎么实现的,调用者不需要关心,只需要提供者提供了这些方法,能供调用就可以。

下面这个看下老师点名的例子,这个例子讲的挺通俗的,时间关系我在这就不做重复举例了: http://blog.csdn.net/lajiooo/article/details/6365239

 

6、开闭原则:OCP(Open Close Principle) 解释为一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化。

开闭原则是一个非常虚的原则,前面5个原则是对开闭原则的具体解释 。用一个我在《设计模式之禅(第二版)》第45页的书店的一个例子讲解下:

public interface IBook {
    public String getName();
    public int getPrice();
    public String getAuthor();
}
public class NovelBook implements IBook {
    private String name;
    private int price;
    private String author;
    
    public NovelBook(String name, int price, String author) {
        this.name = name;
        this.price = price;
        this.author = author;
    }     @Override
    public String getName() {
        return name;
    }     @Override
    public int getPrice() {
        return price;
    }     @Override
    public String getAuthor() {
        return author;
    }
}
public class BookStore {
    private final static ArrayList<IBook> bookList=new ArrayList<IBook>();
    static{
        bookList.add(new NovelBook("天龙八部",3200,"金庸"));
        bookList.add(new NovelBook("巴黎圣母院",5600,"雨果"));
        bookList.add(new NovelBook("悲惨世界",3500,"雨果"));
        bookList.add(new NovelBook("梅",4300,"兰陵笑笑生"));
    }
    public static void main(String[] args) {
        NumberFormat formatter=NumberFormat.getCurrencyInstance();
        formatter.setMaximumFractionDigits(2);
        System.out.println("书店卖出去的书籍记录如下:");
        for(IBook book:bookList){
            System.out.println("书籍名称:"+book.getName()+
                             "\t书籍作者:"+book.getAuthor()+
                             "\t书籍价格:"+formatter.format(book.getPrice()/100.0)+"元");
        }
    }

}

项目已经投产了,但是现在有一个需求,就是所有40元以上的书籍9折销售,其他的书籍8折销售,该怎么去修改程序呢?我想肯定我们不能去修改接口吧,接口是对外的契约,如果修改接口,那要改的地方实在太多了,风险忒大。最直接的想法可能就是直接去修改getPrice()这个方法,这是一个好主意,但是有一个不好的地方,就是修改getPrice()方法之后,显示出来的是打折之后的价格,原来的价格是显示不出来的,这样就没有对比性了,有没有更好的办法呢?这里,让我们来体验一次开闭原则的好处,通过扩展来实现变化,新增了一个OffNovelBook类,继承自NovelBook,并且重写了getPrice()方法,用这个类来处理打折的小说类书籍,不修改原来的代码。新增的类的代码如下:

 1 public class OffNovelBook extends NovelBook {
 2 
 3     public OffNovelBook(String name, int price, String author) {
 4         super(name, price, author);
 5     }
 6 
 7     @Override
 8     public int getPrice() {
 9         int selfPrice=super.getPrice();//原价
         
         int offPrice=0;//打折之后的价格,初始化为0
         if(selfPrice>4000){
             offPrice=selfPrice * 90 / 100;
         }
         else{
             offPrice=selfPrice * 80 / 100;
         }
         
         return offPrice;
     }
 }
 public class BookStore {
     private final static ArrayList<IBook> bookList=new ArrayList<IBook>();
     static{
         bookList.add(new OffNovelBook("天龙八部",3200,"金庸"));
         bookList.add(new OffNovelBook("巴黎圣母院",5600,"雨果"));
         bookList.add(new OffNovelBook("悲惨世界",3500,"雨果"));
         bookList.add(new OffNovelBook("梅",4300,"兰陵笑笑生"));
     }
     public static void main(String[] args) {
         NumberFormat formatter=NumberFormat.getCurrencyInstance();
         formatter.setMaximumFractionDigits(2);
         System.out.println("书店卖出去的书籍记录如下:");
         for(IBook book:bookList){
             System.out.println("书籍名称:"+book.getName()+
                              "\t书籍作者:"+book.getAuthor()+
                              "\t书籍价格:"+formatter.format(book.getPrice()/100.0)+"元");
         }
     }
 
 }    

上面的例子可以很清晰的让我们了解开闭原则定义。

持续更新中........ 

浅析JAVA设计模式(三)的更多相关文章

  1. 浅析JAVA设计模式之工厂模式(一)

    1 工厂模式简单介绍 工厂模式的定义:简单地说,用来实例化对象,取代new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式能够动态决定将哪一个类实例化.不用先知道每次要实例化哪一个类. 工 ...

  2. 浅析JAVA设计模式之工厂模式(二)

    1 工厂方法模式简单介绍 工厂方法 (Factroy Method)模式:又称多态性工厂模式(Polymorphic Factory),在这样的模式中,核心工厂不再是一个详细的类.而是一个抽象工厂,提 ...

  3. 浅析JAVA设计模式(一)

    第一写技术博客,只是想把自己一天天积累的东西与大家分享.今天在看<大型网站架构和java中间件>这本书时,其中提到代理模式的动态代理.作为java中间件的一个重要基础,我觉的有必要整理和分 ...

  4. 浅析JAVA设计模式(二)

    2. 里氏替换原则:LSP(Liskov Substitution Principle)里氏替换原则,定义为只要父类出现的地方子类就可以出现,而且用子类替换后,程序也不会出现问题,使用者根本不用关心是 ...

  5. java设计模式---三种工厂模式之间的区别

    简单工厂,工厂方法,抽象工厂都属于设计模式中的创建型模式.其主要功能都是帮助我们把对象的实例化部分抽取了出来,优化了系统的架构,并且增强了系统的扩展性. 本文是本人对这三种模式学习后的一个小结以及对他 ...

  6. java设计模式三种工厂模式简单介绍

    一.简单工厂模式 概述:简单工厂模式的创建意图就是,把对类的创建初始化全都交给一个工厂来执行,而用户不需要去关心创建的过程是什么样的,只用告诉工厂我想要什么就行了.而这种方法的缺点也很明显,违背了设计 ...

  7. 阿里架构师浅析Java设计模式之虚拟代理模式

    虚拟代理模式(Virtual Proxy)是一种节省内存的技术,它建议创建那些占用大量内存或处理复杂的对象时,把创建这类对象推迟到使用它的时候.在特定的应用中,不同部分的功能由不同的对象组成,应用启动 ...

  8. java设计模式(三)--抽象工厂模式

    转载:http://zz563143188.iteye.com/blog/1847029 前面的工厂方法模式虽然清晰,但还是感觉有些繁琐,通常使用的还是抽象工厂模式. 工厂方法模式有一个问题就是,类的 ...

  9. java设计模式---三种工厂模式

    工厂模式提供创建对象的接口. 工厂模式分为三类:简单工厂模式(Simple Factory), 工厂方法模式(Factory Method)和抽象工厂模式(Abstract Factory).GOF在 ...

随机推荐

  1. 潜语义分析(Latent Semantic Analysis)

    LSI(Latent semantic indexing, 潜语义索引)和LSA(Latent semantic analysis,潜语义分析)这两个名字其实是一回事.我们这里称为LSA. LSA源自 ...

  2. novnc ignoring socket not reay

  3. poj 1459 Power Network【建立超级源点,超级汇点】

    Power Network Time Limit: 2000MS   Memory Limit: 32768K Total Submissions: 25514   Accepted: 13287 D ...

  4. 让BOOTSTRAP默认SLIDER支持触屏设备

    var isTouch=('ontouchstart' in window); if(isTouch){ $(".carousel").on('touchstart', funct ...

  5. NOIopenjudge 407:Heritage

    总时间限制:  5000ms 内存限制:  65536kB 描述 Your rich uncle died recently, and the heritage needs to be divided ...

  6. JAVA自动生成正则表达式工具类

    经过很久的努力,终于完成了JAVA自动生成正则表达式工具类.还记得之前需要正则,老是从网上找吗?找了想修改也不会修改.现在不用再为此烦恼了,使用此生成类轻松搞定所有正则表达式.赶快在同事面前炫一下吧. ...

  7. ThinkPHP函数详解:D方法

    从本篇开始,我们会陆续给大家详细说明下框架内置函数的用法. D方法 D方法应该是用的比较多的方法了,用于实例化自定义模型类,是ThinkPHP框架对Model类实例化的一种封装,并实现了单例模式,支持 ...

  8. 利用dom4j读取xml文件

    对于xml文件的读取,其实有很多方法,例如:SAX实现方法,DOM4J实现方法 ,DOM 实现方法,JDOM实现方法 等等. 下面,我就说下dom4j的读取方法: 1.首先,肯定要引入第三方jar包. ...

  9. logback使用

    须要的jar包: slf4j-api-1.7.7.jar logback-classic-1.1.2.jar logback-core-1.1.2.jar logback.xml配置文件,放在proj ...

  10. Ubuntu安装一:VM安装具体解释

    1.下载VM中文版:http://download.pchome.net/system/sysenhance/down-4673-1.html,解压后双击安装包: 2.点击:下一步 3.允许安装协议, ...