2

为什么构图要遵循“开放扩展,接近修改”的原则?

我理解:如果您想在类中添加功能,您只需编写新代码并使用组合来获取该代码。
但是你只是修改你有组合的代码吗?因为您将组合添加到该代码中,所以您修改了该代码。

例子:

之前,是这样的:

public class Example{
public void Walk(){
    //walking
}
}

之后:

public class Example{

    RunClass r = new RunClass(); // I add this

public void Walk(){
    //walking
}

public void Run(){ // I also add this
    r.run();        
}
}

所以这意味着我修改了这个类。

4

3 回答 3

5

您需要先查看定义。
组合只是一个“有”的关系,而继承是一个“是”的关系。开放封闭原则是关于在不改变类的源代码的情况下改变行为。他们自己并不能确保OCP。
设计模式通过组合或/和继承遵循这一原则。例如,策略设计模式使用组合在运行时改变行为,而模板方法模式使用继承在编译时改变行为。因此,组合允许在运行时进行扩展,因此继承允许在编译时进行扩展。如果您希望您的类被密封(不能被子类化),唯一可用的选项是组合。
除非您的设计是松散耦合的,否则 OCP 并不能通过组合来确保。请记住,组合只是一种“具有”关系,它只是说您的类有一个对象的实例,但是如果您必须修改代码以更改该实例,则不遵循 OCP。但是,如果您使用控制反转 (IoC),则该组合会变得松散耦合,因此您不必更改类中的代码。这是一个例子:

不遵循 OCP 的作文

  public class Bike {
    Wheel wheel = new LargeWheel();

    public void go(){
      wheel.go();
  }

遵循 OCP 的组合(通过 IoC)

  public class Bike {
    Wheel wheel;

    public setWheel(Wheel wheel){
      this.wheel = wheel;
    }

    public void go(){
      wheel.go();
  }

在第一种情况下,如果您想要不同类型的轮子,则需要修改代码,但在第二种情况下,您“注入”所需的轮子实例。

于 2012-04-29T18:20:19.493 回答
2

您没有以 OCP 方式使用合成。

这将遵循 OCP:

public class Example2{

    Example e = new Example(); 
    RunClass r = new RunClass();

    public void Walk(){
        e.Walk()
    }

    public void Run(){ 
        r.run();        
    }
}

另一种方法是Example2继承Example

public class Example2 extends Example{

    RunClass r = new RunClass();

    public void Run(){ 
        r.run();        
    }
}

Example不会改变,但会组合成Example2.

于 2012-04-29T16:19:48.430 回答
0

当你将它应用到一个你没有源代码的类时,open-close 的要点很清楚,它只是作为依赖项出现在 JAR 中。该类已完全关闭以进行修改-您只能按原样使用它。开放部分意味着该类的设计方式应使您作为其使用者能够扩展其行为以满足您的需求。组合是使用该类并添加您自己的行为的一种方式。

于 2012-04-29T17:18:46.043 回答