本文主要针对设计模式的代码实现编写。
1)创建型模式:
工厂方法模式(虚拟构造器)——定义一个对象的接口,但是由子类决定用哪个类来实例化,从而将类的实例化延迟至其子类。当客户不知道要创建哪个具体类的实例或者不想在客户端代码中指明要具体创建的实例时要用工厂方法。静态工厂方法既可以在ADT内部实现,也可以构造单独的工厂类,这种方法与new相比就有指定的更有意义的名称,而且不必每次调用时都创建新的工厂对象,还可以返回原返回类型的任意子类型。但是,工厂方法意味着每增加一种产品都需要增加一个新的工厂子类。
工厂类的实现方法为:
interface Factory(){
Type get(info){}
//Other Operator
}
class AFactory implements Factory{
Type get(info){
if(条件1) return new TypeA;
if(条件2) return new TypeB;
...
}
//Other Operator
}
2)结构型模式:
适配器模式——适配器的目的是将某个类或接口转换为用户期望的其他形式,它能解决类之间接口不兼容的问题,而且通过增加一个接口将已存在的子类封装起来,使得用户面向接口编程,从而隐藏了具体子类。适配器常用的模式就是继承和指派,但是这种组合继承会引发组合爆炸导致大量代码重复。所以使用装饰器。
适配器模式的代码实现:
package adapter;
//目标接口
interface Target
{
public void request();
}
//适配者接口
class Adaptee
{
public void specificRequest()
{
System.out.println("适配者中的业务代码被调用!");
}
}
//类适配器类
class ClassAdapter extends Adaptee implements Target
{
public void request()
{
specificRequest();
}
}
//客户端代码
public class ClassAdapterTest
{
public static void main(String[] args)
{
System.out.println("类适配器模式测试:");
Target target = new ClassAdapter();
target.request();
}
}
装饰器模式——为对象增加不同侧面的特性,对每个特性构造子类型,通过指派机制增加到对象上,本质上是一个递归方式。具体过程为用接口定义装饰物执行的公共操作,然后将其实对象在接口的基础上用通用的方法放到对象中。Decorator是一个抽象类,是所有装饰类的基类,里面包含成员变量comp指向的被装饰对象。具体定义为:public decorator (component input){this.comp=input;}。从而,具体的装饰器类可以加方法。装饰器在运行时形成(而继承是编译),并由多个对象组成,并且可以与不同的装饰器混合。
装饰器模式的实现方法为:
public interface MediaPlayer {
public void play(String audioType, String fileName);
}
AdvancedMediaPlayer.java
public interface AdvancedMediaPlayer {
public void playVlc(String fileName);
public void playMp4(String fileName);
}
public class VlcPlayer implements AdvancedMediaPlayer{
@Override
public void playVlc(String fileName) {
System.out.println("Playing vlc file. Name: "+ fileName);
}
@Override
public void playMp4(String fileName) {
//什么也不做
}
}
public class Mp4Player implements AdvancedMediaPlayer{
@Override
public void playVlc(String fileName) {
//什么也不做
}
@Override
public void playMp4(String fileName) {
System.out.println("Playing mp4 file. Name: "+ fileName);
}
}
public class MediaAdapter implements MediaPlayer {
AdvancedMediaPlayer advancedMusicPlayer;
public MediaAdapter(String audioType){
if(audioType.equalsIgnoreCase("vlc") ){
advancedMusicPlayer = new VlcPlayer();
} else if (audioType.equalsIgnoreCase("mp4")){
advancedMusicPlayer = new Mp4Player();
}
}
@Override
public void play(String audioType, String fileName) {
if(audioType.equalsIgnoreCase("vlc")){
advancedMusicPlayer.playVlc(fileName);
}else if(audioType.equalsIgnoreCase("mp4")){
advancedMusicPlayer.playMp4(fileName);
}
}
}
3)表现型模式:
策略模式——有时有多种不同的算法来实现同一任务,但需要用户根据需要动态切换算法,而不是写死在代码里。解决方案是,为不同的实现算法构造抽象接口,利用指派在运行时动态传入用户倾向的算法类实例。
策略模式的实现代码为:
interface method(){
func()
}
class A implements method{
func();
}
class B implements method{
func();
}
...
模板(template)模式——不同的用户实现相似的功能,即做事情的步骤一样,但具体方法不同。解决方案是共性的步骤在抽象类中实现,差异化的步骤在各个子类中实现。模板方法就定义了一个算法的步骤,并允许子类为一个或多个步骤提供实现。使用继承和重写实现模板模式,这种方法经常应用与框架中。
迭代器(iterator)模式——客户端希望对放入容器或集合类的一组ADT对象进行遍历访问,而无需关心容器的具体类型,也就是说不管对象放在哪里,迭代器提供同样的遍历方式。标准的遍历协议需要三个方法(下一个、是否结束、当前物件),然后借助四迭代器类实现。实现迭代器接口的容器对象应该是可迭代的,从而让自己的集合类实现可迭代接口,并实现自己独特的迭代器(hasNext,next,remove)。
访问者模式(visitor)——对特定类型对象的特定操作(visit),在运行时将二者动态地绑定到一起,该操作可以灵活修改,无需更改被visit的类。本质上就是将数据和作用于数据上的某种特定操作分离出来。这就为ADT预留了一个将来可扩展的功能接入点,外部实现的功能代码可以在不改变ADT本身的情况下通过指派加入到ADT中。访问者和策略虽然都来自指派,但是访问者强调外部定义对ADT的某种操作,它与ADT关系不大(仅使用),所以ADT内部只需开放accept(visitor)即可,用户对齐外部调用;而策略强调对ADT内部某种功能的算法灵活调换,它们是ADT的一部分,只不过是被指派到外部策略类里。
访问者模式的实现代码如下:
package net.biancheng.c.visitor;
import java.util.*;
public class VisitorPattern {
public static void main(String[] args) {
ObjectStructure os = new ObjectStructure();
os.add(new ConcreteElementA());
os.add(new ConcreteElementB());
Visitor visitor = new ConcreteVisitorA();
os.accept(visitor);
System.out.println("------------------------");
visitor = new ConcreteVisitorB();
os.accept(visitor);
}
}
//抽象访问者
interface Visitor {
void visit(ConcreteElementA element);
void visit(ConcreteElementB element);
}
//具体访问者A类
class ConcreteVisitorA implements Visitor {
public void visit(ConcreteElementA element) {
System.out.println("具体访问者A访问-->" + element.operationA());
}
public void visit(ConcreteElementB element) {
System.out.println("具体访问者A访问-->" + element.operationB());
}
}
//具体访问者B类
class ConcreteVisitorB implements Visitor {
public void visit(ConcreteElementA element) {
System.out.println("具体访问者B访问-->" + element.operationA());
}
public void visit(ConcreteElementB element) {
System.out.println("具体访问者B访问-->" + element.operationB());
}
}
//抽象元素类
interface Element {
void accept(Visitor visitor);
}
//具体元素A类
class ConcreteElementA implements Element {
public void accept(Visitor visitor) {
visitor.visit(this);
}
public String operationA() {
return "具体元素A的操作。";
}
}
//具体元素B类
class ConcreteElementB implements Element {
public void accept(Visitor visitor) {
visitor.visit(this);
}
public String operationB() {
return "具体元素B的操作。";
}
}
//对象结构角色
class ObjectStructure {
private List<Element> list = new ArrayList<Element>();
public void accept(Visitor visitor) {
Iterator<Element> i = list.iterator();
while (i.hasNext()) {
((Element) i.next()).accept(visitor);
}
}
public void add(Element element) {
list.add(element);
}
public void remove(Element element) {
list.remove(element);
}
}