抽象类和接口及策略模式介绍(结合抽象类在JFinal方言中的应用)

class vs interface

可能有很多人建议开发者应该把所有的类定义为一系列的interface,但笔者觉得这样的推荐有点极端。当前看到我的程序设计中需要经常更改的情况下才使用interfaces
例如,strategy pattern(策略模式)能够让开发者在应用程序中在不改变对象的前提下随意交换新算法。一个多媒体播放器应用程序中,可以播放cd、mp3、wav等格式的文件。理所当然的,开发者在播放器中不应把播放算法写死,否则当需求添加另外一种格式的多媒体播放算法时会很麻烦。再者,如果不是用策略模式,代码将会变得糟糕,重复写相同语句太多。总之,这将不是一种面向对象的编程方法。
通过strategy pattern,在一个对象中可以很简单地封装一组播放不同格式多媒体文件的算法。而且,在后面项目维护时,开发者随时能够添加一种新的插件式的多媒体格式算法。

class StrategyExample{
    public static void main(String[] args) {
       Context context;
       context = new Context(new oneFormat);
       context. MediaStrategy;

        context = new Context(new twoFormat);
       context. MediaStrategy;

    }

}

interface MediaStrategy{
    void playStream(Stream s);
}

class oneFormat implements MediaStrategy{
    public void playStream(Stream s){
        System.out.println("this is A format")
    }
}

class twoFormat implements MediaStrategy{
    public void playStream(Stream s){
        System.out.println("this is B format")
    }
}

class Context{
    private MediaStrategy strategy;
    public Context(MediaStrategy strategy){
        this.strategy = strategy;
    }

    public void playStream(Stream s){
        this.strategy.playStream(Stream s);
    }
}

Interface VS abstract class

定义为interface或者abstract不是一个二选一的问题。如果一个对象是经常更改的,开发者可以定义一个interface。然而当程序中需要一个特定的行为(方法或者属性,可以定义一个abstract类。在一些应用框架中,abstract class是比较适合的。
其实,abstract classesinterfaces非常相似。开发者不能对它们实例化,两者都包含了一系列实现或者为实现方法的声明。然而,在abstract classes中,开发者可以声明非静态和final的字段,定义public、protected和private的具体方法。需要注意的是:在interfaces中的所有字段必须是static、public、final类型的,所有声明的方法必须是public的。还有一点比较鲜明对比就是:class(包括abstract class)只能派生出一个类,而对于interface,开发者能实现继承多个interfaces

  • 考虑使用abstract  class的情景。
    • 几个联系非常紧密的代码中。
    • 一个类继承了abstract class,这个abstract class与这个类有很多相同的字段、方法;或者被继承的类的访问修改需要比public更多的权限,例如protected、private。
    • 定义非静态non-final字段时,以此能够定义访问和修改这些字段的对象的属性的方法。
  • 考虑使用interface的情景
    • 期望一些关系不是很紧密的类继承的interface。如在jdk中的ComparableCloneable被很多不相干的类继承一样。
    • 期望指定一个特定数据类型的行为,但不关心谁实现了这些行为。
    • 期望充分利用多重继承的类型。

根据jdk中的源码,给出分别利用了abstract classinterface的例子。

  1. abstract class
    jdk中,AbstractMap是一个Abstract类,其是Collections的其中一个。AbstractMap的子类(HashMap、TreeMap、和ConcurrentHashMap)共享了很多方法(get、put、isEmpty、containsKey和containsValue
  2. Interface
    jdk中,HashMap类继承了多个interfaces,分别是SerializableCloneable、和Map<K,V>

    HashMap实例能够被clone、实例化(这意味着该HashMap对象能够被转化为字节流)以及拥有Map的全部功能。

抽象类在JFinal 方言中的应用(JFInal源码导读)

策略模式在Hibernate方言中应用,Dialect类是一个各种类型的数据库的抽象积累。由于不同数据库的持久访问有差异,比如在分页算法上有较大的差异,Dialect不同的子类就代表了一种特定的数据库访问策略。但我们这里主要讨论JFinal框架中数据库方言对策略模式的应用。

在JFinalhttp://www.oschina.net/p/jfinal中,Dialect类是一个抽象类,我们可以看到其实现的各种类型数据库方言:
抽象类和接口及策略模式介绍(结合抽象类在JFinal方言中的应用)_第1张图片

这里只列出MysqlDialect子类的方法:
抽象类和接口及策略模式介绍(结合抽象类在JFinal方言中的应用)_第2张图片


接下来我们继续看JFinal源代码的Config.java文件,默认情况下,JFinal使用的是MySQL数据库:

Dialect dialect = new MysqlDialect();
当然我们也可以在Config.java的构造器中设置自己想要的数据库方言:

在getDialect()方法中获取方言实例:

public Dialect getDialect() {
	return dialect;
}



最后需要说的是,在C3p0和Druid数据库连接池都默认使用MySQL数据库。

你可能感兴趣的:(抽象类和接口及策略模式介绍(结合抽象类在JFinal方言中的应用))