Java_你应该知道的26种设计模式

四。 模板方法模式

Definition: Define the skeleton of an algorithm in an operation, deferring some steps to subclasses.

Templet Method lets subclasses redefine certain steps of an algorithm without changing the algorithm‘s structure.

它包含一个抽象模板和一些具体的模板。

抽象模板中包含两类方法:

  • 基本方法

    • 也叫基本操作,是有抽象模板给出抽象接口,子类给出实现的方法,并且这些方法会在模板方法中被调用;
    • 基本方法尽量设计为protected类型,符合迪米特法则
  • 模板方法
    • 可以有一个或几个,一般是一个具体方法,实现对基本方法的调度,完成固定的逻辑。
    • 为了防止恶意的操作,,一般模板方法都会加上final关键字,不允许被覆写。

Demo Coding:

package com.model;

public abstract class HummerModel {
    /**
     * 首先,这个模型要能发动起来,不管是电力发动还是手摇发动
     * 所以具体是怎么发动就要根据不同的型号自己实现发动的方法
     */
    public abstract void start();

    /**
     * 不仅能够发动,还要能够停止
     */
    public abstract void stop();

    /**
     * 按喇叭会响
     */
    public abstract void alarm();

    /**
     * 发动引擎时有隆隆声
     */
    public abstract void engineBoom();

    public void run() {
        this.start();
        this.engineBoom();
        this.alarm();
        this.stop();
    }
}

package com.model;

public class HummerH1Model extends HummerModel {

    @Override
    public void start() {
        // TODO Auto-generated method stub
        System.out.println("H1型号是这样启动的.....");
    }

    @Override
    public void stop() {
        // TODO Auto-generated method stub
        System.out.println("H1型号是这样停止的.....");
    }

    @Override
    public void alarm() {
        // TODO Auto-generated method stub
        System.out.println("H1型号是这样鸣笛的......");
    }

    @Override
    public void engineBoom() {
        // TODO Auto-generated method stub
        System.out.println("H1型号是这样发动引擎的......");
    }

}

package com.model;

public class HummerH2Model extends HummerModel {

    @Override
    public void start() {
        // TODO Auto-generated method stub
        System.out.println("H2型号是这样启动的......");
    }

    @Override
    public void stop() {
        // TODO Auto-generated method stub
        System.out.println("H2型号是这样停止的......");
    }

    @Override
    public void alarm() {
        // TODO Auto-generated method stub
        System.out.println("H2型号是这样鸣笛的......");
    }

    @Override
    public void engineBoom() {
        // TODO Auto-generated method stub
        System.out.println("H2型号是这样发动引擎的......");
    }

}

package com.model;

public class Client {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //某公司要H1模型的悍马汽车
        HummerModel hm = new HummerH1Model();
        //H1模型演示如下
        hm.run();
    }

}

五。 建造者模式(Builder Pattern)

Definition: Separate the construction of a complex object from its representation so that the same

construction process can create different representations.

在一般的建造者模式中,有如下4个角色:

  • 产品类(实际就是上面的第四种模板方法模式的实现)

    • 通常是实现了模板方法模式,也就是有模板方法和基本方法;
  • 抽象建造者Builder
    • 规范产品的组建,一般由子类实现。
  • 具体构建着ConcreteBuilder
    • 实现抽象建造者的所有方法,并且返回一个组建好的对象
  • 导演类
    • 负责根据客户的需要安排已有模块的顺序,然后告诉Builder开始建造,然后获得ConcreteBuilder返回的对象,最后呈现给客户

所以说,不论是经由模板模式构建的产品类还是抽象或具体的建造者,对于客户都是屏蔽的,客户只需要将他的具体需求告诉导演类,最终由导演类统筹安排,将结果返回给客户。

建造者模式的使用场景有:

  • 如果需求是:相同的方法,不同的执行顺序,产生不同的事件结果时,可以考虑使用。
  • 一个对象由多个零件或部件构成,,但是运行产生的结果又不相同;
  • 所以,,建造者模式关注的是零件类型装配顺序不同!!!这是他与工厂方法最大的不同!!
  • 工厂模式的重点则是创建,创建零件的它的主要职责,组装顺序是它不care的!!

Demo Coding:

/*-------------------------模板方法模式的实现-----------------------------*/
package com.builderPattern;

import java.util.ArrayList;

public abstract class CarModel {
    //这个参数是各个基本方法执行的顺序
    private ArrayList<String> sequence = new ArrayList<String>();

    protected abstract void start();

    protected abstract void stop();

    protected abstract void alarm();

    protected abstract void engineBoom();

    final public void run() {
        //循环一遍sequence,谁在前就限制性谁
        for(int i=0; i<this.sequence.size(); i++) {
            String actionName = this.sequence.get(i);
            if(actionName.equalsIgnoreCase("start"))
                this.start();
            else if(actionName.equalsIgnoreCase("stop"))
                this.stop();
            else if(actionName.equalsIgnoreCase("alarm"))
                this.alarm();
            else if(actionName.equalsIgnoreCase("engine boom"))
                this.engineBoom();
        }
    }

    final public void setSequence(ArrayList<String> sequence) {
        this.sequence = sequence;
    }

}

package com.builderPattern;

public class BenzModel extends CarModel {

    @Override
    protected void start() {
        // TODO Auto-generated method stub
        System.out.println("奔驰是这样run....");
    }

    @Override
    protected void stop() {
        // TODO Auto-generated method stub
        System.out.println("奔驰是这样stop....");
    }

    @Override
    protected void alarm() {
        // TODO Auto-generated method stub
        System.out.println("奔驰是这样alarm....");
    }

    @Override
    protected void engineBoom() {
        // TODO Auto-generated method stub
        System.out.println("奔驰是这样engine boom.....");
    }

}

package com.builderPattern;

public class BMWModel extends CarModel {

    @Override
    protected void start() {
        // TODO Auto-generated method stub
        System.out.println("宝马是这样start....");
    }

    @Override
    protected void stop() {
        // TODO Auto-generated method stub
        System.out.println("宝马是这样stop....");
    }

    @Override
    protected void alarm() {
        // TODO Auto-generated method stub
        System.out.println("宝马是这样alarm....");
    }

    @Override
    protected void engineBoom() {
        // TODO Auto-generated method stub
        System.out.println("宝马是这样engine boom....");
    }

}

/*-------------------------抽象建造者-----------------------------*/
package com.builderPattern;

import java.util.ArrayList;

public abstract class CarBuilder {
    //建造一个模型,你要给我一个顺序,就是组装顺序
    public abstract void setSequence(ArrayList<String> sequence);

    //设置完顺序后,既可以直接拿到这个车辆模型
    public abstract CarModel getCarModel();
}

/*--------------具体建造者的实现,返回一个具体的model------------------------*/
package com.builderPattern;

import java.util.ArrayList;

public class BenzBuilder extends CarBuilder {
    private BenzModel benz = new BenzModel();

    @Override
    public void setSequence(ArrayList<String> sequence) {
        // TODO Auto-generated method stub
        this.benz.setSequence(sequence);
    }

    @Override
    public CarModel getCarModel() {
        // TODO Auto-generated method stub
        return this.benz;
    }

}

package com.builderPattern;

import java.util.ArrayList;

public class BMWBuilder extends CarBuilder {
    private BMWModel bmw = new BMWModel();

    @Override
    public void setSequence(ArrayList<String> sequence) {
        // TODO Auto-generated method stub
        this.bmw.setSequence(sequence);
    }

    @Override
    public CarModel getCarModel() {
        // TODO Auto-generated method stub
        return this.bmw;
    }

}

/*-------------------------导演类的实现,实现客户的需求-------------------------*/
package com.builderPattern;

import java.util.ArrayList;

public class Director {
    private ArrayList<String> sequence = new ArrayList<String>();
    private BenzBuilder benzBuilder = new BenzBuilder();
    private BMWBuilder bmwBuilder = new BMWBuilder();

    /**
     * 获得A类型的奔驰汽车
     * @return
     */
    public BenzModel getABenzModel() {
        this.sequence.clear();

        this.sequence.add("start");
        this.sequence.add("stop");
        this.benzBuilder.setSequence(sequence);
        return (BenzModel) this.benzBuilder.getCarModel();
    }

    /**
     * 获得B类型的奔驰汽车
     * @return
     */
    public BenzModel getBBenzModel() {
        this.sequence.clear();

        this.sequence.add("engine boom");
        this.sequence.add("start");
        this.sequence.add("stop");
        this.benzBuilder.setSequence(sequence);
        return (BenzModel) this.benzBuilder.getCarModel();
    }

    /**
     * 获得A类型的宝马车型
     * @return
     */
    public BMWModel getABMWModel() {
        this.sequence.clear();

        this.sequence.add("alarm");
        this.sequence.add("start");
        this.sequence.add("stop");

        this.bmwBuilder.setSequence(sequence);
        return (BMWModel) this.bmwBuilder.getCarModel();

    }

    /**
     * 获得B类型的宝马车型
     * @return
     */
    public BMWModel getBBMWModel() {
        this.sequence.clear();

        this.sequence.add("start");

        this.bmwBuilder.setSequence(sequence);
        return (BMWModel) this.bmwBuilder.getCarModel();

    }

}

package com.builderPattern;

public class Client {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Director director = new Director();
        //制造100台A类型的奔驰
        for(int i=0; i<1000; i++)
            director.getABenzModel().run();
        for(int i=0; i<2000; i++)
            director.getBBMWModel().run();
    }

}

(-------------------未完待续----------------------)

时间: 2024-10-15 12:43:58

Java_你应该知道的26种设计模式的相关文章

你应该知道的10种软件工具

除非你是设计小型模拟电子电路,不然这年头离开了计算机的帮助,在嵌入式系统设计中很难做成什么事.我觉得我应该分享一个能帮助我完成工作的软件工具列表.它们大多数都是免费的或者比较便宜的.它们大多数也和软件一起工作.如果你向来不需要设计,阅读或者编辑任何软件,那么你属于读了这篇文章不会从中受益的那一小部分人. 免责声明:"最佳"软件工具通常是一种主张.你可能不同意我的主张,那就取其精华吧. 1. 版本控制系统 不管你工作在一个100人的团队,还是独自一人干活,如果你从事设计,你应该会用到版本

Linux 新手应该知道的 26 个命令

当你进入了 Linux 的世界,在下载.安装 了某个 Linux 发行版,体验了 Linux 桌面并安装了一些你喜爱和需要的软件之后,应该去了解下 Linux 真正的魅力所在:命令行.每一个 Linux 命令其实就是一个程序,借助这些命令,我们可以办到非常多的事情.下面将会为大家介绍一下几个常用的命令. 如何寻求帮助? 在 Linux 下遇到问题,最重要的是要自己寻求帮助,下面是三种寻求帮助的方法. man man 是 Linux 的帮助手册,即 manual .因为大多数程序都会自带手册,所以

你应该知道的24种新兴交互设计

在互联网这个领域,每天都有不计其数的产品诞生,有些产品只是灵光一现,有的却存活了下来,但是不论存活与否,这些产品上总有一些设计细节让我们眼前一亮,下文中分类整理了一些不错的交互形式,希望能给大家带来新的设计灵感. 蓝蓝设计一.导航 1,Google+导航的隐藏功能 Google+作为google进入社交领域的第一个产品,在交互方式有很多亮点,比如在导航的扩展性上,可以把不常用的标签拖放到"更多"中,从而使导航界面更简洁,这个操作进行时的效果也很精致.流畅. 2,导航hover 案例一:

26种设计模式

1,简单工厂模式 工厂模式 简单工程模式的最大有点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类.对于客户端来说,去除了与具体产品的依赖. 工程方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类. 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类. 2,建造者模式:(书的uml模型感觉不对) 建造者模式:主要用于创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建

2014年你需要知道的6种编程技能(转)

当开始编程工作时,就会有很多关于你必须学习哪种最热门编程语言的讨论.但跟任何程序员进行讨论的时候,他们会告诉你学习语言并不是学习编程的唯一.同样重要的是要理解组成基础编程语言的核心概念,即算法.数据结构以及学习如何使用技术框架,这些现已成为创造一个伟大的技术产品的精髓. 既然你可以在HackerEarth.com上学习和记录你的算法和数据结构,那么在2014年你应该学一学以下这些技术: Rails 业务逻辑!!有经验的web开发人员都很了解构建一个web应用程序的基本功能所花费的时间.Rails

Linux新手应该知道的26个命令

man man 是 Linux 的帮助手册,即 manual .因为大多数程序都会自带手册,所以可以通过 man 命令获取帮助.执行以后,在 man page 页面中按 q 退出. 获取 ls 的帮助 1 $ man ls 查看有多少(针对不同方面的)同名的手册 1 $ man -f ls 2 ls (1) - list directory contents 3 ls (1p) - list directory contents 查看特定的手册 1 $ man 1p ls info 与 man 

代码面试需要知道的8种数据结构(附面试题及答案链接)

  原文:The top data structures you should know for your next coding interview 译者:Fundebug 为了保证可读性,本文采用意译而非直译.另外,本文版权归原作者所有,翻译仅用于学习. 1976年,一个瑞士计算机科学家写一本书<Algorithms + Data Structures = Programs>.即:算法 + 数据结构 = 程序.40多年过去了,这个等式依然成立. 很多代码面试题都要求候选者深入理解数据结构,

26种设计模式之单例模式

单例模式(Singleton) 保证一个类仅有一个实例,并提供一个访问它的全局访问点. 通常我们可以让一个全局变量使得一个对象被访问 ,但它不能防止你实例化多个对象.一个最好的办法就是,让类自身负责保存它的唯一实例.这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法. class Singleton { private static Singleton instance; private Singleton() { } public static Singleton Get

5种你未必知道的JavaScript和CSS交互的方法(转发)

5种你未必知道的JavaScript和CSS交互的方法 10/08. 2014 随着浏览器不断的升级改进,CSS和JavaScript之间的界限越来越模糊.本来它们是负责着完全不同的功能,但最终,它们都属于网页前端技术,它们需要相互密切的合作.我们的网页中都有.js文件和.css文件,但这并不意味着CSS和js是独立不能交互的.下面要讲的这五种JavaScript和CSS共同合作的方法你也许未必知道! 用JavaScript获取伪元素(pseudo-element)属性 大家都知道如何通过一个元