Java:GOF的23种设计模式(下)

三:构造型模式

(1)建造者模式也叫生成器模式(Builder)

1.建造者模式的意图是把构造对象实例的代码逻辑移到要实例化的类的外部
2.生成器模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

public class Product {

	private String param1;
	private String param2;

	public Product(Builder builder) {
		this.param1 = builder.param1;
		this.param2 = builder.param2;
	}

	private static class Builder {
		String param1;
		String param2;

		Builder param1(String param1) {
			this.param1 = param1;
			return this;
		}

		Builder param2(String param2) {
			this.param2 = param2;
			return this;
		}

		public Product build() {
			return new Product(this);
		}

	}

}



(2)工厂方法模式(Factory Method)

1.工厂方法的主要意图是用于创建对象的接口,同时控制对哪个类进行实例化。
2.定义一个用于创建对象的接口,让子类决定实例化哪一个类。

简单工厂是和工厂方法很相似的一种设计模式,但它不在GOF的23种设计模式之中。它用一个工厂类,里面有个静态方法,通过判断条件来返回不同的实例,也叫静态工厂。以下是工厂方法:

①抽象工厂

package FactoryMethod;
public abstract class Factory {
	public abstract Operation createOperation();
}
②抽象产品类

package FactoryMethod;
public abstract class Operation {
	protected int num1, num2;
	public void setNum1(int num1) {
		this.num1 = num1;
	}
	public void setNum2(int num2) {
		this.num2 = num2;
	}
	public abstract int getResult();
}
③产品类

package FactoryMethod;
public class OperationAdd extends Operation {
	@Override
	public int getResult() {
		// TODO 自动生成的方法存根
		return num1 + num2;
	}
}
package FactoryMethod;
public class OperationSub extends Operation {
	@Override
	public int getResult() {
		// TODO 自动生成的方法存根
		return num1 - num2;
	}
}
④具体工厂类

package FactoryMethod;
public class AddFactory extends Factory{
	@Override
	public Operation createOperation() {
		// TODO 自动生成的方法存根
		return new OperationAdd();
	}
}
package FactoryMethod;
public class SubFactory extends Factory {
	@Override
	public Operation createOperation() {
		// TODO 自动生成的方法存根
		return new OperationSub();
	}
}
⑤Test类

package FactoryMethod;
public class Test {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Factory factory = new AddFactory(); // 用特定的工厂产生特定的对象
		Operation operation = factory.createOperation();
		operation.num1 = 1;
		operation.num2 = 2;
		System.out.println(operation.getResult());
	}
}
可以看到当需要一个功能类时,就应该相应增加一个工厂类。

工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。   
一个抽象工厂类,可以派生出多个具体工厂类。   
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。   
一个抽象工厂类,可以派生出多个具体工厂类。   
每个具体工厂类可以创建多个具体产品类的实例。


(3)抽象工厂模式(Abstract Factory)

1.抽象工厂模式的意图在于创建一系列相互关联或相互依赖的对象。
2.提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

①多个抽象产品类

package a13_AbstractFactory;
public abstract class IUser {
	public abstract void insert(User user);
	public abstract User getUser(int id);
}
package a13_AbstractFactory;
public abstract class IDepartment {
	public abstract void insert(Department department);
	public abstract Department getDepartment(int i);
}
②具体产品类

package a13_AbstractFactory;
public class SqlserverUser extends IUser {
	@Override
	public void insert(User user) {
		// TODO 自动生成的方法存根
		System.out.println("在Sql Server中给User表增加了一条记录");
	}
	@Override
	public User getUser(int id) {
		// TODO 自动生成的方法存根
		System.out.println("在Sql Server中根据ID得到User表一条记录");
		return null;
	}
}
package a13_AbstractFactory;
public class AccessUser extends IUser {
	@Override
	public void insert(User user) {
		// TODO 自动生成的方法存根
		System.out.println("在Access中给User表增加了一条记录");
	}
	@Override
	public User getUser(int id) {
		// TODO 自动生成的方法存根
		System.out.println("在Access中根据ID得到User表一条记录");
		return null;
	}
}
package a13_AbstractFactory;
public class SqlserverDepartment extends IDepartment {
	@Override
	public void insert(Department department) {
		// TODO 自动生成的方法存根
		System.out.println("在Sql Server中给Department表增加了一条记录");
	}
	@Override
	public Department getDepartment(int i) {
		// TODO 自动生成的方法存根
		System.out.println("在Sql Server中给根据ID得到Department表一条记录");
		return null;
	}
}
package a13_AbstractFactory;
public class AccessDepartment extends IDepartment {
	@Override
	public void insert(Department department) {
		// TODO 自动生成的方法存根
		System.out.println("在Access中给Department表添加了一条记录");
	}
	@Override
	public Department getDepartment(int i) {
		// TODO 自动生成的方法存根
		System.out.println("在Access中给根据ID得到Department表一条记录");
		return null;
	}
}
③抽象工厂类

package a13_AbstractFactory;
public abstract class IFactory {
	public abstract IUser creatUser();  //注意,它是可以产生两个不同类型产品对象的,分别对应两个产品抽象类
	public abstract IDepartment createDepartment();
}
④具体工厂类

package a13_AbstractFactory;
public class SqlserverFactory extends IFactory {
	@Override
	public IUser creatUser() {
		// TODO 自动生成的方法存根
		return new SqlserverUser();
	}
	@Override
	public IDepartment createDepartment() {
		// TODO 自动生成的方法存根
		return new SqlserverDepartment();
	}

}
package a13_AbstractFactory;
public class AccessFactory extends IFactory {
	@Override
	public IUser creatUser() {
		// TODO 自动生成的方法存根
		return new AccessUser();
	}
	@Override
	public IDepartment createDepartment() {
		// TODO 自动生成的方法存根
		return new AccessDepartment();
	}
}
⑤差点忘了两个最小单元
package a13_AbstractFactory;

public class User {
	private String name;
	private int id;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
}
package a13_AbstractFactory;

public class Department {
	private String departmentType;
	private int id;
	public String getDepartmentType() {
		return departmentType;
	}
	public void setDepartmentType(String departmentType) {
		this.departmentType = departmentType;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
}
⑥Test类

package a13_AbstractFactory;
public class Test {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		/* 一个抽象产品类 */
		// IFactory factory = new SqlserverFactory();
		// IUser iu = factory.creatUser();
		// User user = new User();
		// iu.insert(user);
		// iu.getUser(1);
		/* 多个抽象产品类 */
		IFactory sqlserverFactory = new SqlserverFactory();
		IUser user = sqlserverFactory.creatUser();
		User concreteUser = new User();
		user.insert(concreteUser);
		user.getUser(1);
		IFactory accessFactory = new AccessFactory();
		IDepartment department = accessFactory.createDepartment();
		Department concreteDepartment = new Department();
		department.insert(concreteDepartment);
		department.getDepartment(1);
	}

}

打印结果:

在Sql Server中给User表增加了一条记录
在Sql Server中根据ID得到User表一条记录
在Access中给Department表添加了一条记录
在Access中给根据ID得到Department表一条记录

(4)原型模式(Prototype)

1.原型模式不通过实例化类来创建一个新的未初始化的实例,而是通过复制一个现有对象来生成新的对象。
2.用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
3.原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需知道任何创建的细节。
概念:
1.浅克隆:被克隆对象的所有变量都含有与原来的对象相同的值,而它所有的对其他对象的引用都仍然指向原来的对象。换一种说法就是浅克隆仅仅克隆所考虑的对象,而不克隆它所引用的对象。 
2.深克隆:被克隆对象的所有变量都含有与原来的对象相同的值,但它所有的对其他对象的引用不再是原有的,而这是指向被复制过的新对象。

①原型类,实现Cloneable接口

package a14_Prototype_2;
public class Prototype implements Cloneable {
	private String name;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Object clone() {
		try {
			return super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
			return null;
		}
	}
}
②具体原型类

package a14_Prototype_1;
public class NewPrototype implements Cloneable {
	private String id;  // 添加了ID属性
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	private Prototype prototype;
	public Prototype getPrototype() {
		return prototype;
	}
	public void setPrototype(Prototype prototype) {
		this.prototype = prototype;
	}
	public Object clone() {
		try {
			return super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
			return null;
		}
	}

}
③Test类

package a14_Prototype_1;

public class Test {
	public static void main(String[] args) {
		//浅克隆,克隆对象copyObj的Prototype对象与原先newObj对象共用一个对象引用
		//而沒有創建一個新的對象,所以可得出下列打印结果
		Prototype pro = new Prototype();
		pro.setName("original object");
		
		NewPrototype newObj = new NewPrototype();
		newObj.setId("test1");
		newObj.setPrototype(pro);

		NewPrototype copyObj = (NewPrototype) newObj.clone();
		copyObj.setId("testCopy");
		copyObj.getPrototype().setName("changed object");

		System.out.println("original object id:" + newObj.getId());
		System.out.println("original object name:"
				+ newObj.getPrototype().getName());

		System.out.println("cloned object id:" + copyObj.getId());
		System.out.println("cloned object name:"
				+ copyObj.getPrototype().getName());
	}
}
打印结果:

original object id:test1
original object name:changed object
cloned object id:testCopy
cloned object name:changed object
要实现深克隆则修改需要具体原型类的clone方法如下:

public Object clone() {
	NewPrototype ret = null;
	try {
		// 将对象本身以及它的引用都克隆下来
		ret = (NewPrototype) super.clone();
		ret.prototype = (Prototype) this.prototype.clone();
		return ret;
	} catch (CloneNotSupportedException e) {
		e.printStackTrace();
		return null;
	}
}
打印结果:

original object id:test1
original object name:original object
cloned object id:testCopy
cloned object name:changed object

(5)备忘录模式(Memento)

1.备忘录模式的意图在于为对象提供状态存储和状态恢复功能
2.备忘录模式可以帮助我们获取对象的状态,以便于将来把对象恢复为以前的状态。
3.在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先的状态。
①发起者类

package a15_Memento;
public class Originator {
	private String state;
	public String getState() {
		return state;
	}
	public void setState(String state) {
		this.state = state;
	}
	public Memento createMemento() {
		return (new Memento(state));
	}
	public void setMemento(Memento memento) {
		state = memento.getState();
	}
	public void show() {
		System.out.println("State:" + state);
	}
}
②备忘录类,相当于存储的信息

package a15_Memento;
public class Memento {
	private String state;
	public Memento(String state) {
		this.state = state;
	}
	public String getState() {
		return state;
	}

}
③管理者类,管理存储的信息

package a15_Memento;
public class Cracker {
	private Memento memento;
	public Memento getMemento() {
		return memento;
	}
	public void setMemento(Memento memento) {
		this.memento = memento;
	}

}
package a15_Memento;
public class Test {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Originator originator = new Originator();
		originator.setState("i am very well");
		originator.show();
		Cracker cracker = new Cracker();
		cracker.setMemento(originator.createMemento());
		originator.setState("i am not good");
		originator.show();
		originator.setMemento(cracker.getMemento());
		originator.show();
	}

}


四:操作型模式

(1)模板方法模式(Template Method)
1.模板方法模式的目的在一个方法中实现一个算法,并将算法中某些步骤的定义推迟,从而使得其他类可以重新定义这些步骤。
2.定义一个操作的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

①抽象模板类,里面的方法有些是抽象的有些是有方法体的

package a16_TemplateMethod;
public abstract class AbstractTemplate {
	public abstract void primitiveOperation1();
	public abstract void primitiveOperation2();
	public void templateMethod() {
		primitiveOperation1();
		primitiveOperation2();
	}
}
②抽象方法的实现类

package a16_TemplateMethod;
public class ConcreteClassA extends AbstractTemplate {
	@Override
	public void primitiveOperation1() {
		// TODO 自动生成的方法存根
		System.out.println("类A模板方法1实现");
	}
	@Override
	public void primitiveOperation2() {
		// TODO 自动生成的方法存根
		System.out.println("类A模板方法2实现");

	}
}
package a16_TemplateMethod;
public class ConcreteClassB extends AbstractTemplate {
	@Override
	public void primitiveOperation1() {
		// TODO 自动生成的方法存根
		System.out.println("类B模板方法1实现");
	}
	@Override
	public void primitiveOperation2() {
		// TODO 自动生成的方法存根
		System.out.println("类B模板方法2实现");

	}
}
③Test类

package a16_TemplateMethod;
public class Test {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		AbstractTemplate at;
		at = new ConcreteClassA();
		at.templateMethod();
		at = new ConcreteClassB();
		at.templateMethod();
	}
}


(2)状态模式(State)

1.状态模式的意图在于将与状态有关的处理逻辑分散到代表对象状态的各个类中
2.当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
3.状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况,把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。而如果这个状态判断很简单,那就没必要用状态模式了。

①抽象状态类

package a17_State;
public abstract class State {
	public abstract void Handle(Context context);
}
②具体状态类

package a17_State;
public class ConcreteStateA extends State {
	@Override
	public void Handle(Context context) {
		// TODO 自动生成的方法存根
		context.setState(new ConcreteStateB());
	}
}
package a17_State;
public class ConcreteStateB extends State {
	@Override
	public void Handle(Context context) {
		// TODO 自动生成的方法存根
		context.setState(new ConcreteStateA());
	}
}
③Context环境类

package a17_State;
public class Context {
	private State state;
	public Context(State state) {
		this.state = state;
	}
	public State getState() {
		return state;
	}
	public void setState(State state) {
		this.state = state;
		System.out.println("当前状态:" + state.getClass().getName());
	}
	public void request() {
		state.Handle(this); //key,控制状态切换
	}

}
④Test类

package a17_State;
public class Test {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Context context = new Context(new ConcreteStateA());
		context.request();
		context.request();
		context.request();
		context.request();
		context.request();
	}
}


(3)策略模式(Strategy)

1.策略模式的意图在于把可选的策略或方案封装在不同的类中,并在这些类中实现一个共同的操作。
2.策略模式定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的用户。

①抽象算法类

package a18_Strategy;
public abstract class Strategy {
	public abstract void algorithm();
}
②具体算法类

package a18_Strategy;
public class concreteStrategyA extends Strategy {
	@Override
	public void algorithm() {
		// TODO 自动生成的方法存根
		System.out.println("算法A实现");
	}
}
package a18_Strategy;
public class concreteStrategyB extends Strategy {
	@Override
	public void algorithm() {
		// TODO 自动生成的方法存根
		System.out.println("算法B实现");
	}
}
package a18_Strategy;
public class concreteStrategyC extends Strategy {
	@Override
	public void algorithm() {
		// TODO 自动生成的方法存根
		System.out.println("算法C实现");
	}
}
③上下文环境类

package a18_Strategy;
public class Context {
	private Strategy strategy;
	public Context(Strategy strategy) {
		this.strategy = strategy;
	}
	public Context(String choice) {
		if (choice.endsWith("A"))
			strategy = new concreteStrategyA();
		else if (choice.equals("B"))
			strategy = new concreteStrategyB();
		else
			strategy = new concreteStrategyC();

	}
	public void run() {
		strategy.algorithm();
	}
}
④Test类

package a18_Strategy;

public class Test {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		String choice = "z";
		// 客户端的判断可以转移到Context类中用简单工厂实现
		// if (choice.endsWith("A"))
		// context = new Context(new concreteStrategyA());
		// else if (choice.equals("B"))
		// context = new Context(new concreteStrategyB());
		// else
		// context = new Context(new concreteStrategyC());
		Context context = new Context(choice);
		context.run();

	}
}

(4)命令模式(command)

1.命令模式的意图是把请求封装在对象中
2.把一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

①抽象命令类

package a19_Command;
public abstract class Command {
	protected Receiver receiver;
	public Command(Receiver receiver) {
		this.receiver = receiver;
	}
	abstract public void execute();
}
②具体命令类

package a19_Command;
public class concreteCommand extends Command {
	public concreteCommand(Receiver receiver) {
		super(receiver);
		// TODO 自动生成的构造函数存根
	}
	@Override
	public void execute() {
		// TODO 自动生成的方法存根
		receiver.action("洗衣服");
	}
}
package a19_Command;
public class concreteCommand1 extends Command {
	public concreteCommand1(Receiver receiver) {
		super(receiver);
		// TODO 自动生成的构造函数存根
	}
	@Override
	public void execute() {
		// TODO 自动生成的方法存根
		receiver.action("做饭");
	}
}
③通知者或者说管理类

package a19_Command;
import java.util.ArrayList;
import java.util.List;
public class Invoker {
	private List<Command> commands = new ArrayList<Command>();
	public void setCommand(Command command) {
		commands.add(command);
	}
	public void execute() {
		for (Command command : commands)
			command.execute();
	}
}
④执行者类

package a19_Command;
public class Receiver {
	public void action(String command) {
		System.out.println(command);
	}
}
⑤Test类

package a19_Command;
public class Test {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Receiver receiver = new Receiver();
		Command command = new concreteCommand(receiver);
		Invoker invoker = new Invoker();
		invoker.setCommand(command);
		invoker.setCommand(command);
		Command command2 = new concreteCommand1(receiver);
		invoker.setCommand(command2);
		invoker.execute();
	}
}

(5)解释器模式(Interpreter)

1.解释器模式的主要意图是可以按照自己定义的组合规则集合来组合可执行对象。
2.给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言的句子。

①抽象表达式类

package a20_Interpreter;
public abstract class AbstractExpression {
	public abstract void interpret(Context context);
}
②具体实现类

package a20_Interpreter;
public class TerminalExpression extends AbstractExpression {

	@Override
	public void interpret(Context context) {
		// TODO 自动生成的方法存根
		System.out.println("终端解释器");
	}
}
package a20_Interpreter;
public class NonterminalExpression extends AbstractExpression {
	@Override
	public void interpret(Context context) {
		// TODO 自动生成的方法存根
		System.out.println("非终端解释器");
	}
}

③上下文环境类,包含解释器以外的一些全局信息

package a20_Interpreter;
public class Context {
	private String input, output;
	public String getInput() {
		return input;
	}
	public void setInput(String input) {
		this.input = input;
	}
	public String getOutput() {
		return output;
	}
	public void setOutput(String output) {
		this.output = output;
	}
}

④Test类

package a20_Interpreter;
import java.util.ArrayList;
import java.util.List;
public class Test {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Context context = new Context();
		List<AbstractExpression> list = new ArrayList<AbstractExpression>();
		list.add(new TerminalExpression());
		list.add(new NonterminalExpression());
		list.add(new TerminalExpression());
		list.add(new TerminalExpression());
		for (AbstractExpression ae : list) {
			ae.interpret(context);
		}
	}
}
其实这个例子感觉不是很好,但又找不到更好的- -


五:拓展型模式

(1)装饰器模式

1.装饰器模式的意图是在运行时组合操作的新变化
2.动态地给一个对象增加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活。

①抽象组件类,可以在此添加职责

package a21_Decorator;
public abstract class Component {
	public abstract void operation();
}
②具体组件类

package a21_Decorator;
public class ConcreteComponent extends Component {

	@Override
	public void operation() {
		// TODO 自动生成的方法存根
		System.out.println("具体对象的操作");
	}
}
③装饰父类

package a21_Decorator;
public class Decorator extends Component {
	protected Component component;
	@Override
	public void operation() {
		// TODO 自动生成的方法存根
		if (component != null) {
			component.operation();
		}
	}
	public void setComponent(Component component) {
		this.component = component;
	}
}
④具体装饰子类

package a21_Decorator;
public class ConcreteDecoratorA extends Decorator {
	@Override
	public void operation() {
		// TODO 自动生成的方法存根
		super.operation();
		addedBehavior();
	}
	private void addedBehavior() {
		System.out.println("装饰A");
	}
}
package a21_Decorator;
public class ConcreteDecoratorB extends Decorator {
	@Override
	public void operation() {
		// TODO 自动生成的方法存根
		super.operation();
		addedBehavior();
	}
	private void addedBehavior() {
		System.out.println("装饰B");
	}
}
⑤Test类

package a21_Decorator;
public class Test {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		ConcreteComponent c = new ConcreteComponent();
		ConcreteDecoratorA d1 = new ConcreteDecoratorA();
		ConcreteDecoratorB d2 = new ConcreteDecoratorB();
		d1.setComponent(c);
		d2.setComponent(d1);
		d2.operation();
	}
}

(2)迭代器模式(Iterator)

1.迭代器模式的意图在于为开发人员提供一种顺序访问集合元素的方法
2.提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。

①抽象集合类

package a22_Iterator;
public abstract class AbstractAggregate {
	public abstract void add(Object obj);
	public abstract void remove(Object obj);
	public abstract AbstractIterator iterator();
}
②抽象迭代器类

package a22_Iterator;
public abstract class AbstractIterator {
	public abstract Object next();
	public abstract boolean hasNext();
}
③具体集合类
package a22_Iterator;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
class ConcreteAggregate extends AbstractAggregate {
	private List list = new ArrayList();
	public void add(Object obj) {
		list.add(obj);
	}
	public AbstractIterator iterator() {
		return new ConcreteIterator(list);
	}
	public void remove(Object obj) {
		list.remove(obj);
	}
}

④具体迭代器

package a22_Iterator;
import java.util.ArrayList;
import java.util.List;
class ConcreteIterator extends AbstractIterator {
	private List list = new ArrayList();
	private int cursor = 0;
	public ConcreteIterator(List list) {
		this.list = list;
	}
	public boolean hasNext() {
		if (cursor == list.size()) {
			return false;
		}
		return true;
	}
	public Object next() {
		Object obj = null;
		if (this.hasNext()) {
			obj = this.list.get(cursor++);
		}
		return obj;
	}
}
⑤Test类,迭代器因其常用性,现在很多语言都直接支持了。

package a22_Iterator;
public class Test {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		AbstractAggregate ag = new ConcreteAggregate();
		ag.add("1");
		ag.add("2");
		ag.add("3");
		AbstractIterator it = ag.iterator();
		while (it.hasNext()) {
			String str = (String) it.next();
			System.out.println(str);
		}
	}

}


(3)访问者模式(Visitor)

1.访问者模式的意图在于让代码用户能够在不修改现有类层次结构的前提下,定义该类层次结构的相关操作。
2.表示一个作用于某对象结构中各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

3.访问者模式适用于数据结构相对稳定的系统

①抽象访问者类

package a23_Visitor;
public abstract class Visitor {
	public abstract void visitConcreteElementA(ConcreteElementA a);
	public abstract void visitConcreteElementB(ConcreteElementB b);
}
②具体访问者类

package a23_Visitor;
public class ConcreteVisitor1 extends Visitor {
	@Override
	public void visitConcreteElementA(ConcreteElementA a) {
		// TODO 自动生成的方法存根
		System.out.println(a.getClass().getName() + "被"
				+ this.getClass().getName() + "访问");
	}
	@Override
	public void visitConcreteElementB(ConcreteElementB b) {
		// TODO 自动生成的方法存根
		System.out.println(b.getClass().getName() + "被"
				+ this.getClass().getName() + "访问");
	}
}
package a23_Visitor;
public class ConcreteVisitor1 extends Visitor {
	@Override
	public void visitConcreteElementA(ConcreteElementA a) {
		// TODO 自动生成的方法存根
		System.out.println(a.getClass().getName() + "被"
				+ this.getClass().getName() + "访问");
	}
	@Override
	public void visitConcreteElementB(ConcreteElementB b) {
		// TODO 自动生成的方法存根
		System.out.println(b.getClass().getName() + "被"
				+ this.getClass().getName() + "访问");
	}
}
③抽象元素类,被访问的元素

package a23_Visitor;
public abstract class Element {
	public abstract void accept(Visitor visitor);
}
④具体元素类

package a23_Visitor;
public class ConcreteElementA extends Element {
	@Override
	public void accept(Visitor visitor) {
		// TODO 自动生成的方法存根
		visitor.visitConcreteElementA(this);
	}
}
package a23_Visitor;
public class ConcreteElementB extends Element {
	@Override
	public void accept(Visitor visitor) {
		// TODO 自动生成的方法存根
		visitor.visitConcreteElementB(this);
	}
}
⑤组织类,提供一个高层接口以允许访问者访问它的元素

package a23_Visitor;
import java.util.ArrayList;
import java.util.List;
public class ObjectStructure {
	private List<Element> list = new ArrayList<>();
	public void attach(Element element) {
		list.add(element);
	}
	public void detach(Element element) {
		list.remove(element);
	}
	public void accept(Visitor visitor) {
		for (Element element : list) {
			element.accept(visitor);
		}
	}
}
⑥Test类

package a23_Visitor;
public class Test {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		ObjectStructure os = new ObjectStructure();
		os.attach(new ConcreteElementA());
		os.attach(new ConcreteElementB());
		ConcreteVisitor1 cv1 = new ConcreteVisitor1();
		// ConcreteVisitor2 cv2 = new ConcreteVisitor2();
		os.accept(cv1);
		// os.accept(cv2);
	}
}


    终于整理完了,现在再叫我写上述23个设计模式的大部分模式,我都是写不出来的。 某年某月某日看到某些代码时,可以惊觉这怎么这么像之前学的那些设计模式的?这样我的学习的目标就达到了。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值