java设计模式--基础思想总结--抽象类与架构设计思想

抽象类?这个东西我感觉没什么卵用啊,又不能拿来new对象,没有具体的对象的抽象类,有什么实际的意义呢?这是很多刚刚接触java抽象类语法时的第一反应(当然,包括我)。确实,很多刚刚接触抽象类这个概念的程序员都无法真正理解抽象类存在的意义,感觉java中的这个专门只能拿来继承并实现了对应抽象方法才能真正有那么一点用处的父类确实有点多余。

确实,如果你只是一个应用开发者(当然,是指简单地实现业务功能),或许你永远也不用抽象类,因为,它本来就不是拿来当具体的应用功能开发用的类,它是用来实现传说中的架构建模用的,没错,就是这个简答的抽象类,是架构师构建大型架构必不可少的工具,废话不多说,下面我们一起感受抽象类在架构设计中的威力(当然,真正的 威力肯定比我描述的强大得多,毕竟,目前我对抽象类的架构建模思想也是懂点皮毛,或许皮毛都不算)

一、具体类实现功能

  在讨论抽象类前,我们先简单地讨论具体类的一些例子,以便和抽象类进行对比,好了,首先看一个很稀松例子:

//一个简单的汽车类
class Car{
    //该类有以下方法
    
    //点火方法
    public void fire(){
        System.out.println("我是汽车,给我点火,我的发动机会开始转动");
    }
    
    //驾驶方法
    public void run(){
        System.out.println("我是车,我现在在驾驶,注意,我和倒车不同,我是向前走");
    }
    //倒车方法
    public void backCar(){
        System.out.println("我是车,我现在在倒车,注意,我和驾驶不同,我是向后走");
    }
    
    //现在有一个动作:放置好车辆(好吧,这个说法有点牵强,只是为了说明例子,别太在意)
    public void setCar(){
        //首先,你要对车点火才能驱动车行驶,才能将车放到车库(原谅我这里的不面向对象,一切只为说明问题实质)
        fire();
        //恩,向前走,去到车库
        run();
        //ok,我要倒车入库了
        backCar();
        //...当然,后续其他操作:熄火啊什么的
    }
}

好吧,代码有点长,可能你现在一脸懵逼不知道我为毛举一个这么脑残的例子(稍后估计你就明白了),这里的代码就是我们平时很多时候编程的大概思维方式:类方法内部调用其他方法,而且这个类是具体的,方法也是具体的,我们当时想的只是:我要事先车这个功能,例如说,我只是要倒车入库,我现在实现了,那就行啦,这样代码运行的不错,恩,我们开始沾沾自喜,感觉自己干了件大事,觉得java程序设计不过如此,简单啦。

确实,上面这个例子,在现阶段,很好地实现了我们需要的功能,然而,然而,估计你是个程序员,你就会知道,需求,一直在变,程序也要一直变,正如我的上一篇讨论设计模式的博客说到:我们要保证我们的设计具有可扩展性。

所以,看看我们上面这个例子的可扩展性如何:加入,我的车不是普通的车,我的车是宝马,宝马啊,他妈的怎么能和普通车一样?我的run方法可是时速超过200km的,你怎么能只是简单地说我只是在往前走地描述我的驾驶状态?所以,这是候,上面的代码没辙了,只能新建一个BMW类,然后乖乖地继承car类,然后乖乖地重写所有方法,然后,你会发觉:这个更高级别的car存在的意义似乎并不大?下面是继承后的BMW类的代码:

class Bmw extends Car{
    //我是宝马,我的点火方法与众不同
    public void fire(){
        System.out.println("我是宝马,给我点火,我的发动机会开始转动,并且哥点火时的气势可不是那些普通车可比的");
    }
    
    //宝马驾驶方法
    public void run(){
        System.out.println("我是宝马,我现在在驾驶,注意,我是在飞奔驾驶,别将我和那些垃圾普通奇瑞qq类比");
    }
    //宝马倒车方法
    public void backCar(){
        System.out.println("我是车,我现在在倒车,因为我是宝马,倒车姿势肯定也不是一般酷");
    }
    
    //现在要放好我的宝马车了
    public void setCar(){
        //首先,轰轰,点火
        fire();
        //恩,向前飞奔,注意,是飞奔
        run();
        //ok,我要倒车入库了
        backCar();
        //...当然,后续其他操作:熄火啊什么的
    }
}

所以,作为程序员的你开始抱怨:为毛感觉父类在这里没什么作用了?它作用表现在哪?我还不是要重新全部方法覆盖一遍!所以,这时候,抽象类的威力就出来,下面看用抽象类改造后的例子;

二、抽象类进行更高层次的建模

  先看利用抽象类进行更高层次的建模吧,估计看完代码你就大概能领悟抽象类再架构设计中是大概如何发挥作用的了:

//我是一个抽象的汽车类,注意,是抽象的
abstract class car{
    //和上面例子一样,我有下面这些方法,只不过,部分方法抽象化了
    public abstract void fire();
    public abstract void run();
    public abstract void backCar();
    //然后,下面这个方法不是抽象的(是的,java抽象类允许非抽象方法存在),因为,它对应所有的car都适用(也是高层次进行动作抽象的表现)
    public void setCar(){
        //我调用抽象方法,不用担心,这些抽象方法会在子类中实现!
        fire();
        run();
        backCar();
    }
}

好了,有没有领会到我大概要表达的意思和传递的思想了呢:在上面中,我就是利用car的抽象类,定义了setCar的具体方法,这是因为对应所有车来说setCar都是这几个动作(fire,run,backCar),所以,这是确定的——setCar必须肯定是调用这几个方法的,所以具体化;而fire,run,backCar针对不同的车有不同的方式,所以要抽象化,然后,子类只需要实现抽象类具体方法就行了,然后,对于所有的car来说,我们可以复用父类的setCar代码(毕竟所有车的setCar动作一样),而,这,不就是基础的好处了吗?好了,看下面的BMW家伙在利用抽象类进行建模后的改进写法:

class Bmw extends car{
    public void fire() {
        System.out.println("我是宝马,给我点火,我的发动机会开始转动,并且哥点火时的气势可不是那些普通车可比的");
    }

    public void run() {
        System.out.println("我是宝马,我现在在驾驶,注意,我是在飞奔驾驶,别将我和那些垃圾普通奇瑞qq类比");
    }
    public void backCar() {
        System.out.println("我是车,我现在在倒车,因为我是宝马,倒车姿势肯定也不是一般酷");
    }
    //然后,我们就可以直接复用car父类中的setCar方法啦!直接调用即可,达到了复用代码的目的!
}

这时,估计你应该能体会到抽象类的一些威力了吧?它在更高的层次进行一个类组织的规范,这个抽象类知道大体上这个类该如何组织,如何运行,但是运行细节其实子类来决定的(子类实现对应抽象方法),这些,不正是很多web框架设计的常用手段吗!

所以,架构就这样来了,架构师在更高层次抽象系统的类之间、类内部的调度关系,而实现开发人员只需要实行具体的方法就可以了,毕竟,类之间的关系,架构师已经规划好了。

另外,这样还有另外的好处就是:扩展性。我想新增一种车,只需要基础抽象类Car即可,setCar操作会根据我新的类型的car的方法进行不同的内部动作,而我原来的代码并不需要一点点的改变!这样,符合扩展的不修改源代码而利用新增代码达到扩展的原则。

So,抽象类,的确,很不错是吧,毕竟,虽然它不是具体的执行者(不能new),但是,它充当的确实帝王角色,专门负责指挥具体的方法去做事,所以我认为:抽象类的设计,就是一套系统的架构规范的设计!

原文地址:https://www.cnblogs.com/lcplcpjava/p/6629620.html