java 完全解耦[编程思想之9.4]

策略设计模式

示例

package com.ebao.java.interfaces9;

public class Processor {
 public String name(){
  return this.getClass().getSimpleName();
 }
 Object process(Object input){
  return input;
 }
}

public class Upcase extends Processor {
 String process(Object input){
  return ((String)input).toUpperCase();
 }
}

public class Downcase extends Processor {
 String process(Object input){
  return ((String)input).toLowerCase();
 }
}

public class Splitter extends Processor {
 String process(Object input){
  return Arrays.toString(((String)input).split(" "));
 }
}

public class Apply {
 public static void process(Processor p, Object s){
  System.out.println("Using Processor "+p.name());
  System.out.println(p.process(s));
 }
 public static String s = "Disagreement with beliefs is by definition incorrect";
 public static void main(String[] args){
  process(new Upcase(),s);
  process(new Downcase(),s);
  process(new Splitter(),s);
 }
}

运行结果:

Using Processor Upcase
DISAGREEMENT WITH BELIEFS IS BY DEFINITION INCORRECT
Using Processor Downcase
disagreement with beliefs is by definition incorrect
Using Processor Splitter
[Disagreement, with, beliefs, is, by, definition, incorrect]

Apply.process()方法可以接受任何类型的Process,并将其应用到一个Object对象上,然后打印结果。像上例这样,创建一个能够根据所传递的参数对象的不同而具有不同行为的方法,被称为策略设计模式。这类方法包含所要执行的算法中固定不变的部分,而“策略”包含变化的部分。策略就是传递进去的参数对象,它包含要执行的代码。这里,Processor对象就是一个策略,在main()中可以看到有三种不同类型的策略应用到了String类型的s对象上。

示例二:

package com.ebao.java.interfaces9;

public class Waveform {
private static long counter;
private final long id = counter++;
public String toString(){
 return "Waveform "+id;
}
}

public class Filter{
 public String name(){
  return this.getClass().getSimpleName();
 }
}

public class LowerPass extends Filter {
 double cutoff;
 public LowerPass(double cutoff){
  this.cutoff = cutoff;
 }
 public Waveform process(Waveform input){
  return input;
 }
}

public class HighPass extends Filter {
 double cutoff;
 public HighPass(double cutoff){
  this.cutoff = cutoff;
 }
 public Waveform process(Waveform input){
  return input;
 }
}

public class BandPass extends Filter {
 double lowCutoff,hightCutoff;
 public BandPass(double lowCutoff,double hightCutoff){
  this.lowCutoff = lowCutoff;
  this.hightCutoff = hightCutoff;
 }
 public Waveform process(Waveform input){
  return input;
 }
}

Filter与Processor具有相同的接口元素,但是因为它并非继承自Processor——因为Filter类的创建者压根不清楚你想要将它用作Processor——因此你不能将Filter用于Apply.process()方法。这里主要是因为Apply.process方法和Processor之前的耦合过紧,已经超出了所需要的程序,这就使得应该利用Apply.process()的代码时,利用却被禁止了。另外还有它们的输入和输出都是Waveform。

但是,如果Processor是个接口,那么这些限制就会变得松动,使得你可以复用结构该接口的Apply.process()。下面是Processor和Apply的修改版本:

package com.ebao.java.interfaces9;

public interface Processor02 {
 String name();
 Object process(Object input);
}

public class Apply02 {
 public static void process(Processor02 p, Object s){
  System.out.println("Using Processor "+p.name());
  System.out.println(p.process(s));
 }
}

public abstract class StringProcessor implements Processor02 {

public String name() {
  return this.getClass().getSimpleName();
 }

public abstract String process(Object input);
 public static String s = "Disagreement with beliefs is by definition incorrect";
 public static void main(String[] args){
  Apply02.process(new Upcase02(),s);
  Apply02.process(new Downcase02(),s);
  Apply02.process(new Splitter02(),s);
 }
}

public class Upcase02 extends StringProcessor {

public String process(Object input) {
  return ((String)input).toUpperCase();
 }
}

public class Downcase02 extends StringProcessor {

public String process(Object input) {
  return ((String)input).toLowerCase();
 }
}

public class Splitter02 extends StringProcessor {

public String process(Object input) {
  return Arrays.toString(((String)input).split(" "));
 }
}

抽象类继承接口时可以不用继承接口方法。

但是,经常会碰到的情况是你无法修改你想要使用的类。例如,在电子滤波器的例子啊,类库是被发现而非被修建。在这些情况下,可以使用适配器设计模式。适配器中的代码将接受你所拥有的接口,并产生你所需要的接口,就像下面这样:

package com.ebao.java.interfaces9;

public class FilterAdapter implements Processor02 {
 Filter filter;
 public FilterAdapter(Filter filter){
  this.filter = filter;
 }

public String name() {
  return filter.name();
 }

public Waveform process(Object input) {
  return filter.process((Waveform)input);
 }
}

public class FilterProcessor {
 public static void main(String[] args){
  Waveform w = new Waveform();
  Apply02.process(new FilterAdapter(new LowerPass(1.0)), w);
  Apply02.process(new FilterAdapter(new HighPass(2.0)), w);
  Apply02.process(new FilterAdapter(new BandPass(3.0,4.0)), w);
 }
}

在使用这种适配器的方式中,FilterAdapter的构造器接受你所拥有的接口Filter,然后生成具有你所需要的Processor接口对象。你可能还注意到了,在FilterAdapter类中用到了代理。将接口从具体实现中解耦使得接口可以适用于多种不同的实现,因此代码就更具有可利用性。

例如再写个Example类,有一个方法,对其进行适配

package com.ebao.java.interfaces9;

public class Example {
 public String exchange(String s){
  return "Example: "+s;
 }
}

public class ExampleAdapter implements Processor02 {
 private Example ep;
 public ExampleAdapter(Example ep){
  this.ep = ep;
 }

public String name() {
  return ep.getClass().getSimpleName();
 }

public String process(Object input) {
  return ep.exchange((String)input);
 }
}

public class ExampleProcessor {
 public static void main(String[] args){
  Apply02.process(new ExampleAdapter(new Example()), "fengying");
 }
}

运行结果:

Using Processor Example
Example: fengying

时间: 2024-10-28 14:23:44

java 完全解耦[编程思想之9.4]的相关文章

Java编程思想(前十章)

Java编程思想 有C++编程基础的条件下, 前10章可以快速过一下,都是基本语法,不需要花太多时间. 着重中后段的一些章节,类型信息.泛型.容器.IO.并发等. 中文翻译版 阅读地址 对于一个架构师而言,掌握各种语言的优势并可以运用到系统中,由此简化系统的开发,是其架构生涯的第一步. 每一个程序员都不能固步自封,要多接触新的行业,新的技术领域,突破自我. 对象入门 类的继承一般使用'统一标记法'(UML图)来画继承的图. 在面向对象的程序中, 通常要用到上溯造型(向上转型)的技术, 需要动态绑

异常笔记--java编程思想

开一个新的系列,主要记一些琐碎的重要的知识点,把书读薄才是目的...特点: 代码少,概念多... 1. 基本概念 异常是在当前环境下无法获得必要的信息来解决这个问题,所以就需要从当前环境跳出,就是抛出异常.抛出异常后发生的几件事: 1.在堆上创建异常对象. 2.当前的执行路径中止                                          3. 当前环境抛出异常对象的引用.                                         4. 异常处理机制接

《Java编程思想》第十三章 字符串

<Java编程思想>读书笔记 1.String作为方法的参数时,会复制一份引用,而该引用所指的对象其实一直待在单一的物理位置,从未动过. 2.显式地创建StringBuilder允许预先为他指定大小.如果知道字符串多长,可以预先指定StringBuilder的大小避免多次重新分配的冲突. 1 /** 2 * @author zlz099: 3 * @version 创建时间:2017年9月1日 下午4:03:59 4 */ 5 public class UsingStringBuilder {

Java编程思想 4th 第2章 一切都是对象

Java是基于C++的,但Java是一种更纯粹的面向对象程序设计语言,和C++不同的是,Java只支持面向对象编程,因此Java的编程风格也是纯OOP风格的,即一切都是类,所有事情在类对象中完成. 在Java中,使用引用来操纵对象,在Java编程思想的第四版中,使用的术语是"引用(reference)",之前有读过Java编程思想第三版,在第三版中,使用的术语是"句柄(handle)",事实上,我觉得第三版的术语"句柄"更加形象传神,就像你用一个

JAVA编程思想导论(猜字谜游戏1.0)

一. 引言 本章将借用一个简易的猜字谜游戏,向读者简单介绍JAVA面向对象的部分知识以及实现思路. 二. 面向对象思想导论 为了了解什么是面向对象,我们需要解决以下几点问题(如图2.1所示): 面向对象是什么? 面向对象的特征(或者说表现形式). 为什么要面向对象(它与面向过程的区别). 面向对象该怎么做? 众所周知,计算机的编程语言是始于对机器的模仿,即以代码的形式控制机器完成人们希望所能达到的任务或者效果,故而所有编程语言都提供了抽象机制. 而这种抽象机制实际上可以这么认为——人们所能够解决

《Java编程思想(第4版)》pdf

下载地址:网盘下载 内容简介 编辑 本书赢得了全球程序员的广泛赞誉,即使是最晦涩的概念,在Bruce Eckel的文字亲和力和小而直接的编程示例面前也会化解于无形.从Java的基础语法到最高级特性(深入的面向对象概念.多线程.自动项目构建.单元测试和调试等),本书都能逐步指导你轻松掌握.[1] 从本书获得的各项大奖以及来自世界各地的读者评论中,不难看出这是一本经典之作.本书的作者拥有多年教学经验,对C.C++以及Java语言都有独到.深入的见解,以通俗易懂及小而直接的示例解释了一个个晦涩抽象的概

Java编程思想总结笔记Chapter 2

本章介绍Java程序的基本组成部分,体会到Java中几乎一切都是对象. 第二章   一切都是对象 目录: 2.1 用引用操纵对象 2.2 必须由你创建所有对象 2.3 永远不需要销毁对象 2.4 创建新的数据类型:类 2.5 方法.参数和返回值 2.6 构建一个Java程序 2.7 你的第一个Java程序 2.8 注释和嵌入式文档 2.9 编码风格 2.1 用引用操纵对象 一切都看作对象,操纵的标识符实际上是对象的一个"引用",遥控器(引用)操纵电视机(对象),想调控电视,只需通过遥控

《java编程思想》有必要买吗

<java编程思想>有必要买吗 1.看到过好多个这样的提问,其实我一般真的不那么容易分享自己的这点心得的,这是第一次回答这样的"推荐书籍"方面的问题. 我买编程方面的书籍,有一个非常清晰.坚决的原则--电子工业出版社的! 对于JAVA,建议你看如下的书: 首先,<21天学通JAVA>: 然后,<30天学通JAVA项目案例开发>(这本书的内容都是实例的,非常棒的实例!适合初学者的同时,又有实际应用性!) 以上的书籍,是基于你只想学J2SE的. 我还建议

JAVA编程思想(第四版)学习笔记----4.8 switch(知识点已更新)

switch语句和if-else语句不同,switch语句可以有多个可能的执行路径.在第四版java编程思想介绍switch语句的语法格式时写到: switch (integral-selector) { case integral-value1: statement; break; case integral-value12: statement; break; default: statement; } 其中integral-selector(整数选择因子)是一个能产生整数值的表达式.并且说