软件设计 2017-04-08
一、策略设计模式
创建一个能够根据所传递对象的不同而具有不同行为的方法被称为策略设计模式;这类方法包含所要执行的算法中固定不变的部分,而“策略”包含变化的部分。策略就是传递进去的参数对象,它包含要执行的代码。
这种设计模式将算法分别独立封装起来,然后将其当做参数传递给方法从而让方法产生不同的行为,不同的算法可以进行替换(就像给方法不同的实参)。我们可以知道,在策略设计模式中有三个部分:策略、策略引用、接收策略引用的方法(这是笔者自己根据理解给出的名词,并没有查询有没有这些术语)。下面通过一个例子简单介绍一下策略设计模式:
package com.tongye.strategy; /* 基类,这里可以是普通类,也可以是一个接口 */ abstract class Shape{ public abstract void outputShape(); } /* 策略 */ class Circle extends Shape{ public void outputShape(){ System.out.println("this is a circle"); } } /* 策略 */ class Square extends Shape{ public void outputShape(){ System.out.println("this is a square"); } } /* 策略 */ class Triangle extends Shape{ public void outputShape(){ System.out.println("this is a triangle"); } } public class Strategy { /* Strategy.strategic()方法接收一个Shape类型的引用作为参数 * 这个引用可以是任何类型的Shape,如Circle、Square、Triangle * 根据所传递参数的不同,strategic方法有不同的行为略 * */ public static void strategic(Shape S){ // 接收策略引用的方法,S是策略引用 S.outputShape(); // 方法中固有不变的部分 } public static void main(String[] args){ strategic(new Circle()); // 新建Circle()对象作为strategic()方法的参数,这里的circle()对象就是一个策略,这里用到了向上转型 strategic(new Square()); // 策略Square()对象 strategic(new Triangle()); // 策略Triangle()对象 } } /* * output: * this is a circle * this is a square * this is a triangle * */
通过上面的一小段代码,我们知道,strategic方法可以根据所传递参数的不同而产生不同的行为,这些行为被封装在不同的策略中,这就是策略设计模式。通过将不同的行为封装到不同的策略中,我们可以随时更换策略从而实现不同的行为,从而使得程序更为灵活,更易于维护。
二、适配器模式
举个简单的例子,当我们给手机充电时,由于手机充电口是5V,而插座提供的是220V交流电,因此我们通常需要使用充电器将220V交流电转换成可供手机充电用的5V直流电,这个充电器就是一个适配器。
同样,在编写JAVA程序时,我们可能会遇到这样一种情况:我们需要一个类A来实现接口B,但是类A并没有实现接口B中的所有方法,而类A是不能被改变的,这时我们可以创建一个类C,它继承类A并实现接口B,这个类C就是一个适配器。适配器中的代码将接受你所拥有的接口,并产生你所需要的接口。适配器模式有两张:类适配器模式和对象适配器模式。下面用两个例子来简单演示一下:
1、类适配器模式:
/*****************************/ package com.tongye.adapters; public interface TargetInterface { void method1(); void method2(); } /*****************************/ package com.tongye.adapters; /* 源类,我们需要这个类实现接口 TargetInterface,但这个类不能被改变 * 源类与接口之间是没有关系的 * */ class BeAdapted{ public void method1(){ System.out.println("method1"); } } /* 这是适配器,它接受了BeAdapted中已有的接口并产生我们需要的接口 * method1()方法继承自BeAdapted类(即已有的接口),不用再作声明 * 这里适配器的作用相当于为源类与接口之间建立了一种关系,类似于 implements * */ class Adapter extends BeAdapted implements TargetInterface{ public void method2(){ // method2()方法无法通过继承获得,因而需要自己声明,这就是适配器为我们产生的接口 System.out.println("method2"); } } public class ClassAdapter { public static void main(String[] args){ Adapter adapt = new Adapter(); adapt.method1(); adapt.method2(); } }
Adapter与BeAdapted是继承关系,即为类适配器模式。
2、对象适配器模式:
/*****************************/ package com.tongye.adapters; public interface TargetInterface { void method1(); void method2(); } /*****************************/ package com.tongye.adapters; /* 源类,我们需要这个类实现接口 TargetInterface,但这个类不能被改变 * 源类与接口之间是没有关系的 * */ class BeAdapted{ public void method1(){ System.out.println("method1"); } } /* 这是适配器,它接受了中已有的接口并产生我们需要的接口 */ class Adapter implements TargetInterface{ private static BeAdapted adapted; // 声明一个BeAdapted对象引用 public Adapter(BeAdapted adapted){ // 构造方法,接收一个BeAdapted引用作为参数 this.adapted = adapted; } public void method1(){ // method1()在源类BeAdapted中有,这里直接委派 this.adapted.method1(); } public void method2(){ // method2()方法无法通过继承获得,需要自己声明 System.out.println("method2"); } }
Adapter与BeAdapted是委托关系,即为对象适配器模式。
通过使用适配器模式,可以大大提升程序的灵活性以及代码的可重复性。
注:笔者在第一次在书上看到策略设计模式和适配器模式时,并没有看懂,感觉云里雾里的,于是去网上找了一下别人的经验贴,其中有一位博主(java_my_life)写的博客十分简明易懂,讲的也很全面,我就是看了他的博客才感觉恍然大悟的,这里贴一下那位博主的两篇博客的地址:
http://www.cnblogs.com/java-my-life/archive/2012/05/10/2491891.html
http://www.cnblogs.com/java-my-life/archive/2012/04/13/2442795.html
前几篇介绍了设计模式的特性并且详细讲解了4种创建型模式,创建型模式是负责如何产生对象实例的,接下来讲讲结构型模式。结构型模式是解析类和对象的内部结构和外部组合,通过优化程序结构解决模块之间的耦合问题。