一、开闭原则
1.定义
开闭原则:对扩展开放,对修改关闭。
2.具体用法
在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。
想要达到这样的效果,我们需要使用接口和抽象类。
因为抽象灵活性好,适应性广,只要抽象的合理,可以基本保持软件架构的稳定。而软件中易变的细节可以从抽象派生来的实现类来进行扩展,当软件需要发生变化时,只需要根据需求重新派生一个实现类来扩展就可以了。
3.代码举例
public class Client {
    public static void main(String[] args) {
        //创建搜狗输入法
        SouGouInput souGouInput = new SouGouInput();
        //创建皮肤对象
        DefaultSkin defaultSkin = new DefaultSkin();
        //将皮肤设置到输入法
        souGouInput.setSkin(defaultSkin);
        //显示皮肤
        souGouInput.display();
    }
}
public abstract class AbstractSkin {
    //显示的方法
    public abstract void display();
}
public class DefaultSkin extends AbstractSkin{
    public void display(){
        System.out.println("默认皮肤 ");
    }
}
public class CSDNSkin extends AbstractSkin{
    @Override
    public void display() {
        System.out.println("欢迎使用Theodore的皮肤!");
    }
}
public class SouGouInput {
    private AbstractSkin skin;
    public void setSkin(AbstractSkin skin) {
        this.skin = skin;
    }
    public void display(){
        skin.display();
    }
}
 
4.案例讲解
(1)抽象类 AbstractSkin:为扩展皮肤做好准备
public abstract class AbstractSkin { 
    public abstract void display(); 
} 
- 这是一个 抽象类,定义了一个抽象方法 
display(),用来显示皮肤。 - 为什么要这样设计? 
  
- 这样做的目的是:为未来新增不同的皮肤提供扩展能力。只要继承这个抽象类并实现 
display方法,就可以定义新的皮肤。 
 - 这样做的目的是:为未来新增不同的皮肤提供扩展能力。只要继承这个抽象类并实现 
 - 开闭原则体现: 
  
- 对扩展开放:未来我们可以新增任何皮肤类,而不需要修改 
AbstractSkin类本身。 - 对修改关闭:无需修改 
AbstractSkin类的代码,只需要新增子类实现新的功能。 
 - 对扩展开放:未来我们可以新增任何皮肤类,而不需要修改 
 
(2)具体皮肤类 DefaultSkin 和 CSDNSkin:通过扩展实现新功能
public class DefaultSkin extends AbstractSkin { 
    public void display() { 
        System.out.println("默认皮肤"); 
    } 
} 
public class CSDNSkin extends AbstractSkin { 
    @Override public void display() { 
        System.out.println("欢迎使用Theodore的皮肤!"); 
    } 
}
 
- 这里我们定义了两个具体的皮肤类,分别是默认皮肤和 CSDN 皮肤。
 - 开闭原则体现: 
  
- 对扩展开放:如果以后你想新增一个皮肤,比如说 “暗黑皮肤”,只需要新建一个 
DarkModeSkin类,继承AbstractSkin,并实现display方法。 - 对修改关闭:你无需修改 
DefaultSkin和CSDNSkin的代码,就可以新增新的皮肤类。 
 - 对扩展开放:如果以后你想新增一个皮肤,比如说 “暗黑皮肤”,只需要新建一个 
 
(3)输入法类 SouGouInput:通过抽象类实现扩展性
public class SouGouInput {
    private AbstractSkin skin; // 依赖于抽象类
    public void setSkin(AbstractSkin skin) {
        this.skin = skin;
    }
    public void display() {
        skin.display();
    }
}
 
SouGouInput类表示搜狗输入法,它并不知道有哪些具体皮肤,只知道这些皮肤都是AbstractSkin的子类。- 开闭原则体现: 
  
- 对扩展开放:你可以传入任何 
AbstractSkin的子类,比如DefaultSkin、CSDNSkin或未来的DarkModeSkin。 - 对修改关闭:
SouGouInput类的代码并不需要因为新增了新皮肤而进行任何修改。 
 - 对扩展开放:你可以传入任何 
 
(4)客户端类 Client:使用不同皮肤而不改动输入法
public class Client {
    public static void main(String[] args) {
        SouGouInput souGouInput = new SouGouInput();
        
        // 使用默认皮肤
        souGouInput.setSkin(new DefaultSkin());
        souGouInput.display();
        
        // 切换到 CSDN 皮肤
        souGouInput.setSkin(new CSDNSkin());
        souGouInput.display();
    }
}
 
输出结果:
默认皮肤 欢迎使用Theodore的皮肤!
- 开闭原则体现: 
  
- 在客户端中,
SouGouInput可以使用任意的皮肤,而无需修改SouGouInput类的核心逻辑。 - 如果想新增一个皮肤,比如暗黑皮肤,只需要这样写: 
新增的皮肤功能可以被无缝集成,而无需对已有代码做出修改。souGouInput.setSkin(new DarkModeSkin()); souGouInput.display(); 
 - 在客户端中,
 
5.总结
通过这个例子,我们可以看到,开闭原则 是如何帮助我们设计出 灵活且易于扩展 的代码结构:
- 抽象类 
AbstractSkin提供扩展点:所有新皮肤都通过继承这个类来扩展功能。 SouGouInput类依赖抽象类,而不是具体实现:这让输入法系统无需修改现有代码即可使用新的皮肤。- 新增功能不改动现有代码:新增皮肤只需创建新的子类,不需要修改 
SouGouInput和已有的皮肤类。 
这样,我们既能满足用户不断变化的需求(比如新增不同风格的皮肤),又能保证现有代码的稳定性,减少修改代码引入错误的风险。



















