”对修改关闭,对拓展开放“。 
一个书店卖书的例子,见代码
public interface IBook {
    public String getName();
    public int getPrice();
    public String getAuthor();
}
----------
package com.sdkd.hms;
public class NovelBook implements IBook {
    private String  name;
    private int price;
    private String author;
    public NovelBook(String name, int price, String author) {
        super();
        this.name = name;
        this.price = price;
        this.author = author;
    }   
    @Override
    public String getName() {
        // TODO Auto-generated method stub
        return this.name;
    }
    @Override
    public int getPrice() {
        // TODO Auto-generated method stub
        return this.price;
    }
    @Override
    public String getAuthor() {
        // TODO Auto-generated method stub
        return this.author;
    }
}
----------
package com.sdkd.hms;
import java.text.NumberFormat;
import java.util.ArrayList;
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("金瓶梅",2147483647,"兰陵笑笑生"));
    }
    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));
        }
    }
}
/*
----------书店的卖出去的书记录如下-------
书籍名称:天龙八部   书籍作者:金庸 书籍价格¥32.00
书籍名称:巴黎圣母   书籍作者:雨果 书籍价格¥56.00
书籍名称:悲惨世界   书籍作者:雨果 书籍价格¥35.00
书籍名称:金瓶梅    书籍作者:兰陵笑笑生  书籍价格¥21,474,836.00
*/
ok,现在全球经济下滑,书店为了生存开始打折销售:所有40以上的书9折,其他的8这,我们应该如何应对这样一个需求变化? 
三种方法: 
1、修改接口。在IBook接口中加一个getOffPrice()方法。可是这样你需要修改NovelBook类,你也需要修改main中的方法。嗯…. 
2、修改实现类。直接在getPrice()中实现打折处理,这个办法挺好的,但是也有缺陷。例如采购书籍人员也是要看价格的,由于该方法已经实现了打折处理价格,因此采购的人看到的也是打折处理价格,这就不太好了,会因信息不对称而出现决策失误的情况 
3、通过拓展实现变化
public class OffNovelBook extends NovelBook {
    public OffNovelBook(String name, int price, String author) {
        super(name, price, author);
    }
    @Override
    public int getPrice(){
        int selfPrice = super.getPrice();
        int offPrice = 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("金瓶梅",2147483647,"兰陵笑笑生"));
    }
    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));
        }
    }
}
其实这种方法也是会修改代码,但我们修改的高层模块,对其他的类没有影响~
开闭原则看起来简单。但我们也要在最开始的时候架构好代码。 
有重要的一点是: 
将变化的部分封装起来; 
将不变的部分封装起来
原文:http://blog.csdn.net/tyronerenekton/article/details/52210912