设计模式-模版方法

发布于 2023-07-22 21:34:18 字数 5557 浏览 40 评论 0

模板方法算是种较为常见的设计模式,同时对于大多数场景来说也很实用。在面临多算法交换更替使用的情况下,模板方法为你提供了各种算法的“开关”,提高算法的代码复用度。


举例

不画类图了,直接上代码示例。

这是算法的模板抽象类,process*() 是算法的每个步骤,execute() 则是完整得执行算法。

public abstract class PublicExecute {
    public int process1() {
        return 0; 
    }
    public void process2(int i) {
        System.out.println("打印        >>>>>    " + i);
    }
    public abstract void process3();
    //执行算法
    public void execute() {
        process2(process1());
        process3();
    }
}

下面有两个继承 PublicExecute 并实现其抽象方法的实现类,补充了算法的完整性。

//算法1
public class Execute1 extends PublicExecute {
    @Override
    public void process3() {
        // TODO Auto-generated method stub
        System.out.println("完成        >>>>>    Execute1");
    }    
    public void process2(int i) {
        System.out.println("打印        >>>>>    " + (i + 100));
    }
}
//算法2
public class Execute2 extends PublicExecute {
    @Override
    public void process3() {
        // TODO Auto-generated method stub
        System.out.println("完成        >>>>>    Execute2");
    }    
}

上述代码可见,Execute1 实现了 process3(),也同时重写 process2(int i)Execute2 仅仅实现了 process3()

/*
 *     我觉得模板方法应该不难看懂,说白了就是重写算法每个步骤的实现方法。
 */
public class TemplateMethod {
    public static void main(String[] args) {
        PublicExecute execute1 = new Execute1();
        PublicExecute execute2 = new Execute2();    
        /*
         * 打印        >>>>>    100
         * 完成        >>>>>    Execute1
         */
        execute1.execute();
        /*
         * 打印        >>>>>    0
         * 完成        >>>>>    Execute2
         */
        //execute2.execute();
    }
}

JDK 中的模板方法模式

jdk 可谓是设计模式之集大成,肯定少不了模板方法的。

public class Arrays {
    public static void sort(Object[] a) {
        if (LegacyMergeSort.userRequested)
            legacyMergeSort(a);
        else
            ComparableTimSort.sort(a);
    }    

    /** To be removed in a future release. */
    private static void legacyMergeSort(Object[] a) {
        Object[] aux = a.clone();
        mergeSort(aux, a, 0, a.length, 0);
    }

    /**
     * Src is the source array that starts at index 0
     * Dest is the (possibly larger) array destination with a possible offset
     * low is the index in dest to start sorting
     * high is the end index in dest to end sorting
     * off is the offset to generate corresponding low, high in src
     * To be removed in a future release.
     */
    private static void mergeSort(Object[] src,
                                  Object[] dest,
                                  int low,
                                  int high,
                                  int off) {

        // Insertion sort on smallest arrays
        if (length < INSERTIONSORT_THRESHOLD) {
            for (int i=low; i<high; i++)
                for (int j=i; j>low &&
                         ((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)
                    swap(dest, j, j-1);
            return;
        }
        /*
         *    略
         */
        // If list is already sorted, just copy from src to dest.  This is an
        // optimization that results in faster sorts for nearly ordered lists.
        if (((Comparable)src[mid-1]).compareTo(src[mid]) <= 0) {
            System.arraycopy(src, low, dest, destLow, length);
            return;
        }

        // Merge sorted halves (now in src) into dest
        for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
            if (q >= high || p < mid && ((Comparable)src[p]).compareTo(src[q])<=0)
                dest[i] = src[p++];
            else
                dest[i] = src[q++];
        }
    }
}

JDK中java.util.Arrays 的 sort 方法就是典型的模版方法,而从私有方法 mergeSort 来看,为我们提供算法修改的方法则是 Object 的 compareTo

写个 compareTo 的例子

class Dick implements Comparable<Dick> {

    private String name;
    private int size;

    public Dick(String name, int size) {
        super();
        this.name = name;
        this.size = size;
    }

    @Override
    public String toString() {
        return "Dick [name=" + name + ", size=" + size + "cm]";
    }

    // 实现Comparable接口
    @Override
    public int compareTo(Dick o) {
        // TODO Auto-generated method stub
        if(this.size == o.getSize())
            return 0;
        else if(this.size >= o.getSize())
            return 1;
        else
            return -1;
    }

}

测试、打印

public class TestArraysSort {
    public static void main(String[] args) {
        Dick[] fuckers = {new Dick("张三", 17),
                            new Dick("李四", 14), 
                            new Dick("王五", 29), 
                            new Dick("老六", 22), 
                            new Dick("赵七", 11)};
        Arrays.sort(fuckers);
        for(Dick fucker : fuckers)
            System.out.println(fucker);
    }
}

结果:

Dick [name=赵七, size=11cm]
Dick [name=李四, size=14cm]
Dick [name=张三, size=17cm]
Dick [name=老六, size=22cm]
Dick [name=王五, size=29cm]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

文章
评论
28 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文