很多人会觉得矛盾,拓展开放--修改关闭? 如果不能修改如何拓展呢。但是其实是提供方对扩展开放。使用方对修改关闭。
这样讲比较抽象:
例子:
public class Ocp { public static void main(String[] args) { AnimalAct.speak(new Dog()); AnimalAct.speak(new Cat()); } } class AnimalAct { static void speak(Animal animal){ if(animal.animalName.equals("dog")){ System.out.println("汪汪汪"); }else if(animal.animalName.equals("cat")){ System.out.println("喵喵喵"); } } } class Animal { public String animalName; } class Dog extends Animal{ public Dog(){ super(); super.animalName = "dog"; } } class Cat extends Animal{ public Cat(){ super(); super.animalName = "cat"; } }
代码很简单,就是不同动物,打印不同叫声。那么现在问题来了,如果新加了动物羊,那么代码就变成了:
public class Ocp { public static void main(String[] args) { AnimalAct.speak(new Dog()); AnimalAct.speak(new Cat()); AnimalAct.speak(new Sheep()); } } class AnimalAct { static void speak(Animal animal){ if(animal.animalName.equals("dog")){ System.out.println("汪汪汪"); }else if(animal.animalName.equals("cat")){ System.out.println("喵喵喵"); } //修改的地方 else if(animal.animalName.equals("sheep")){ System.out.println("咩咩咩"); } } } class Animal { public String animalName; } class Dog extends Animal{ public Dog(){ super(); super.animalName = "dog"; } } class Cat extends Animal{ public Cat(){ super(); super.animalName = "cat"; } } //修改的地方 class Sheep extends Animal{ public Sheep(){ super(); super.animalName = "sheep"; } }
可以看到要修改两处地方。其中Animal是提供方,AnimalAct是使用方。可以看到两方均要修改代码。
我们尝试代码这么写:
public class Ocp { public static void main(String[] args) { AnimalAct.speak(new Dog()); AnimalAct.speak(new Cat()); AnimalAct.speak(new Sheep()); } } class AnimalAct { static void speak(Animal animal){ animal.speak(); } } class Animal { public String animalName; public void speak(){} } class Dog extends Animal{ public Dog(){ super(); super.animalName = "dog"; } @Override public void speak(){ System.out.println("汪汪汪"); } } class Cat extends Animal{ public Cat(){ super(); super.animalName = "cat"; } @Override public void speak(){ System.out.println("喵喵喵"); } } //修改的地方 class Sheep extends Animal{ public Sheep(){ super(); super.animalName = "sheep"; } @Override public void speak(){ System.out.println("咩咩咩"); } }
这样我们再新加一个动物的时候,就是可以直接修改提供方,重写父类的speak方法。这样就可以达到不修改使用方。