美文网首页Java 杂谈
面向对象之极限思维法

面向对象之极限思维法

作者: 賈小強 | 来源:发表于2019-02-17 09:49 被阅读0次

    简书 賈小強
    转载请注明原创出处,谢谢!

    在我的上篇文章中对面向对象进行了分析,这篇文章将采用高中解题中用的极限思维法来比较面向过程和面向对象,从而让人直观的知道看到什么样的代码就知道那样的代码用面向对象的方法更加合适,可以降低复杂度

    一般而言面向对象的程序需要先经过面向对象分析,然后将系统分成不同的类,各自负责一些责任,并且类之间存在交互,但是这并不是万能的,很多时候由于开始没有考虑到,直到当代码写到那里的时候才发现还需要什么,从而代码逐渐就恶化,复杂性陡增,进入了代码的穷凶极恶之地

    这篇文章继续从代码的角度来分析,优点是和重构一样,知道了坏味道,那么就可以想办法改进,也就说开始不用十全十美,中途发现坏味道的时候还能挽救

    坏味道

    首先假设一份原始代码如下,采用极限思维的方法,把下面变量想象的更多,参数传递更加复杂,各种交错,一团乱麻

    public class Demo1 {
        private void method0() {
            //part1
            int a = 1;
            int b = 2;
            int c = 3;
            int d = 4;
            int e = 5;
            int f = 6;
            int g = 7;
            int h = 8;
            int i = 9;
            int j = 10;
            int k = 11;
            int l = 12;
    
            //part2
            //一些别的代码
            a++;
            c++;
            //一些别的代码
            h++;
            //part3
            int x = method2(g, h, i, j, k, l);
            //一些别的代码执行导致a b c变动,变动后的a b c后面代码还将使用
            for (int m = 0; m < 10; m++) {
                a++;
                b--;
                --c;
            }
    
            System.out.println(a + b + c + d + e + f + x);
        }
    
        private int method2(int g, int h, int i, int j, int k, int l) {
            return g + h + i + j + k + l;
        }
    
    
        public static void main(String[] args) {
            Demo1 demo = new Demo1();
            demo.method1();
        }
    }
    

    输出

    71
    

    这份代码有如下问题:

    1. part1部分:有很多变量的声明赋值
    2. part2部分:由于代码实际逻辑原因,上面的变量操作被间隔开了,虽然从某种角度上,这些变量还有有关系的
    3. part3部分:这样的代码很可能随带的有过长参数,当然也可能与多返回值,以及引用传递等问题

    改进

    将上面变量以及相关操作提取一个类,也就演变成如下两个类

    public class Demo2 {
        private void method0() {
            //part1
            Xx xx = new Xx();
    
            //part2
            //一些别的代码
            xx.method1();
            xx.method2();
            //一些别的代码
            xx.method3();
            //part3
            //一些别的代码执行导致a b c变动,变动后的a b c后面代码还将使用
            xx.method4();
            xx.method5();
            System.out.println(xx.method6());
        }
    
    
        public static void main(String[] args) {
            Demo2 demo = new Demo2();
            demo.method1();
        }
    }
    
    public class Xx {
        private int a;
        private int b;
        private int c;
        private int d;
        private int e;
        private int f;
        private int g;
        private int h;
        private int i;
        private int j;
        private int k;
        private int l;
    
        public Xx() {
            this.a = 1;
            this.b = 2;
            this.c = 3;
            this.d = 4;
            this.e = 5;
            this.f = 6;
            this.g = 7;
            this.h = 8;
            this.i = 9;
            this.j = 10;
            this.k = 11;
            this.l = 12;
        }
    
        public void method1() {
            a++;
        }
    
        public void method2() {
            c++;
        }
    
        public void method3() {
            h++;
        }
    
        public void method4() {
            for (int m = 0; m < 10; m++) {
                a++;
                b--;
                --c;
            }
        }
    
        public int method5() {
            return g + h + i + j + k + l;
        }
    
        public int method6() {
            int x = method5();
            return a + b + c + d + e + f + x;
        }
    }
    

    输出

    71
    

    改进后part1,part2,part3在Demo2中不再有上面提到的问题,在Demo2中的代码中只看到了xx这个对象,于是method0这部分的逻辑清爽多了

    扩展

    据说面向对象这种编程方法在GUI程序中非常适合,细想一下确实没错,每个不同的控件都有各自的属性,并且也各自有不同的方法,有的控件可以继承从而复用代码,要是采用面向过程的方法,可能各种状态变量传来传去,很快就将是场灾难,而采用面向对象的方式组织代码相较就科学很多

    但是抛开这种直观可视化具体和现实世界有对应关系的对象,真实的代码中还有很多没有形状不可见抽象的的概念的对象,如果在程序设计之初没有考虑到,可以用上面提取类的方法来用面向对象的方式,来识别并简化代码,让代码的复杂性在可控范围之内

    Happy learning !!

    相关文章

      网友评论

        本文标题:面向对象之极限思维法

        本文链接:https://www.haomeiwen.com/subject/jjgweqtx.html