在说明柔性多态之前先看看下面多态的设计

 

一般常规的多态程序设计,首先定义多态接口

public interface IShape3 {
    public float getArea();
}

然后在实体类中重写多态函数

public class Circle3 implements IShape3 {
    float r;
    public Circle3(float r){
        this.r = r;
    }
    public float getArea(){
        return r*r*(float)Math.PI;
    }
}
public class Rect3 implements IShape3 {
    private float width,height;
    public Rect3(float width,float height){
        this.width = width;
        this.height = height;
    }
    public float getArea(){
        return width*height;
    }
}

客户端通过动态绑定对接口编程实现了求圆或长方形面积功能。但是考虑一个问题,如果以后需要求图形的周长,那上面这个例子该如何修改?

思路是:重新定义接口IShape3,添加所需要的接口函数(求周长),然后再在继承该接口的对象(Circle3和Rect3)中再实现函数功能。

这样做的后果就是使接口以及实现模块,客户端程序都需要重新修改并且重新编译。但是在实际开发维护中,我们只希望仅仅在底层具体模块功能可以修改并编译,

而接口,上层模块以及客户端程序不需要更改或重新编写。

由此可以看到普通多态的局限性:如果接口函数内容发生变化,那么相应的各实现子类必须发生变化,导致相关联的各级模块必须重新编写和编译。而造成原因莫过于父类与自己的多态函数关联过强。

柔性多态的设计就是正是为了消除这种局限性,下面对上面提到的例子加以“改造”。

定义柔性多态接口

public interface IShape2 {
    public Object dispatch(int nID,Object in);
}

具体实现类

public class Circle2 implements IShape2{
    public float r;
    public Circle2(float r){
        this.r = r;
    }
    public Object dispatch(int nId,Object in){
        Object obj = null;
        switch (nId){
            case 0:
                obj = getArea(in) ;break;
            case 1:
                obj = getPerimeter(in);break;
        }
        return obj;
    }
    Object getArea(Object in){
        float area = (float)Math.PI*r*r;
        return new Float(area);
    }
    Object getPerimeter(Object in){
        float len = (float)Math.PI*r*2.0f;
        return new Float(len);
    }
}

柔性多态的设计思想如下:

1.接口内容固定,如上面IShape2中仅仅定义一个多态接口方法dispatch()

2.子类中重写动态函数dispatch仅仅起到转发作用,且转发的具体函数都不是多态函数。这与第一个例子中多态接口编程思想不一致。

假若现在需要添加新的功能,如求内接三角形的周长。现在只需要在Circle2类中添加一个普通方法getTriLength(),并且在多态函数中添加一个case开关,调用getTriLength()就可以了。

而对接口IShape2根本没有修改。从而削弱了接口类和实现类的强关联,这就是实现柔性多态的关键。

package interfaceAndAbstract.Polymorphism;

/**
 * Created by lenovo on 2017/4/15.
 */
public class Circle2 implements IShape2{
    public float r;
    public Circle2(float r){
        this.r = r;
    }
    public Object dispatch(int nId,Object in){
        Object obj = null;
        switch (nId){
            case 0:
                obj = getArea(in) ;break;
            case 1:
                obj = getPerimeter(in);break;
            case 2:
                obj = getTriLength(in);break;
        }
        return obj;
    }
    Object getArea(Object in){
        float area = (float)Math.PI*r*r;
        return new Float(area);
    }
    Object getPerimeter(Object in){
        float len = (float)Math.PI*r*2.0f;
        return new Float(len);
    }
    Object getTriLength(Object in){
        //具体实现代码
        return null;
    }
}
View Code

相关文章:

  • 2021-12-26
  • 2021-07-15
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-08-13
  • 2022-12-23
猜你喜欢
  • 2021-12-19
  • 2022-12-23
  • 2022-12-23
  • 2021-09-08
相关资源
相似解决方案