个人了解设计模式

个人理解设计模式

设计模式有很多...

 

一. 工厂模式

 

工厂方法

 

抽象类(或接口):

public abstract class Window {
	public abstract void func();
}

实现类:

public class WindowBig extends Window {
	public void func() {
		System.out.println("This is Big Window !");
	}
}
public class WindowSmall extends Window {
	public void func() {
		System.out.println("This is Small Window !");
	}
}

工厂类:

public class Factory {
	public Window CreateWindow(String type) {
		if (type.equals("Big")) {
			return new WindowBig();
		} else if (type.equals("Small")) {
			return new WindowSmall();
		} else {
			return new WindowBig();
		}
	}

	// The Main function only for our test
	public static void main(String[] args) {
		Factory myFactory = new Factory();
		Window myBigWindow = myFactory.CreateWindow("Big");
		myBigWindow.func();

		Window mySmallWindow = myFactory.CreateWindow("Small");
		mySmallWindow.func();
	}
}

 

抽象工厂:

沿用上面工厂方法的 抽象类以及实现类。

抽象工厂接口:

public interface IFactory {
	Window CreateWindow (Window window);
}

抽象工厂的实现类:

public class Factory implements IFactory {
    public Window CreateWindow (Window window) {
    	return window;
    }

    // The Main function only for our test
    public static void main(String[] args) {
    	IFactory myFactory = new Factory();
    	Window windowBig = new WindowBig();
        Window myBigWindow = myFactory.CreateWindow(windowBig);
        myBigWindow.func();

    	Window windowSmall = new WindowSmall();
        Window mySmallWindow = myFactory.CreateWindow(windowSmall);
        mySmallWindow.func();
    }
}

抽象工厂总结:

工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。
抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

 

 

二. Prototype

 

①为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。

②在派生类中覆盖基类的clone()方法,并声明为public。

③在派生类的clone()方法中,调用super.clone()。

④在派生类中实现Cloneable接口。

 

优点:可以节省大量的接口实现类的编写。采用工厂模式的话,如果分别为用户指定的每种场合都提供一个用户接口工厂类,将会为我们带来繁重的工作量。未来避免用户接口工厂类不断增加,可以考虑使用Prototype模式。

缺点:Java中的原型方法不允许新对象拥有与父对象不同的方法。这时候,在使用原型方法之前,需要仔细考虑原型方法的利弊,甚至要试一下Prototype模式是否满足需求。

 

三. Builder模式(建造者模式)

 

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.

 

四. Singleton(单例模式)

形式一:

public class Singleton {
	private Singleton() {
	}

	// 在自己内部定义自己一个实例,是不是很奇怪?
	// 注意这是private 只供内部调用
	private static Singleton instance = new Singleton();

	// 这里提供了一个供外部访问本class的静态方法,可以直接访问  
	public static Singleton getInstance() {
		return instance;
	}
}

形式二:

public class Singleton {
	private static Singleton instance = null;
	public static synchronized Singleton getInstance() {
		// 这个方法比上面有所改进,不用每次都进行生成对象,只是第一次
		// 使用时生成实例,提高了效率!
		if (instance == null)
			instance = new Singleton();
		return instance;
	}
}

上面第二中形式是lazy initialization,也就是说第一次调用时初始Singleton,以后就不用再生成了。

注意到lazy initialization形式中的synchronized,这个synchronized很重要,如果没有synchronized,那么使用getInstance()是有可能得到多个Singleton实例。关于lazy initialization的Singleton有很多涉及double-checked locking (DCL)的讨论,有兴趣者进一步研究。

 

五. Facade(外观)

为子系统中的一组接口提供一个一致的界面.

用自己的话来讲,就是对模块组件进行封装(提取重复的代码,工具类)。

 

六. 动态代理

接口:

public interface IHello {
	void sayHello(String name);
	void sayGoogBye(String name);
}

实现类:

public class Hello implements IHello {
	public void sayHello(String name) {
		System.out.println("Hello " + name);
	}
	public void sayGoogBye(String name) {
		System.out.println(name + " GoodBye!");
	}
}

写一个代理类.让这个类去实现java.lang.reflect.InvocationHandler接口

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DynaProxyHello implements InvocationHandler {

	private Object delegate;

	public Object bind(Object delegate) {
		this.delegate = delegate;
		return Proxy.newProxyInstance(
				this.delegate.getClass().getClassLoader(), this.delegate
						.getClass().getInterfaces(), this);
	}

	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object result = null;
		try {
			// 执行原来的方法之前记录日志
			Logger.logging(Level.DEBUGE, method.getName() + " Method end .");

			// JVM通过这条语句执行原来的方法(反射机制)
			result = method.invoke(this.delegate, args);
			// 执行原来的方法之后记录日志
			Logger.logging(Level.INFO, method.getName() + " Method Start!");
		} catch (Exception e) {
			e.printStackTrace();
		}
		// 返回方法返回值给调用者
		return result;
	}

}

测试:

public class Test {
	public static void main(String[] args) {
		IHello hello = (IHello) new DynaProxyHello().bind(new Hello());
		hello.sayGoogBye("Double J");
		hello.sayHello("Double J");
	}
}

 

七. Adapter( 适配器)模式

一、原理图:
个人了解设计模式
 
二、示例代码

 

/*
 * 源角色
 */
public class Adaptee {
    public int get220v(){
       return 220;
    }
}
 
 /*
 * 目标角色
 */
public interface Target {
    int get110v();
    int get220v();
} 
 
/*
 * 适配器角色:扩展源角色,实现目标角色,从而使得目标角色改动时候,不用改动源角色,只要改动适配器
 */
public class Adapter extends Adaptee implements Target{
    public int get110v(){
        return 110;
    }
}
 
/*
 * 客户端
 */
public class Client {
    public static void main(String rags[]) {
        new Client().test();
    }

    public void test() {
        Target target = new Adapter();
        int v1 = target.get110v();
        int v2 = target.get220v();
    }
}
适配器通过扩展源角色,同时实现目标接口,从而满足了同时提供220v,110v电压的要求。

总结下:
代理模式vs适配器模式vs外观模式

一、定义

代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。

适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口,使得原本接口不兼容而不能一起工作的那些类可以一起工作。

外观模式(Facade):为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

二、理解

代理模式和适配器模式应该说很相像,但是他们的区别也很明显,代理模式和被代理者的接口是同一个,只是使用中客户访问不到被代理者,所以利用代理间接的访 问,而适配器模式,是因为接口不同,为了让用户使用到统一的接口,把原先的对象通过适配器让用户统一的使用,大多数运用在代码维护的后期,或者借用第三方 库的情况下 ,而外观模式,是大家经常无意中使用的,就是把错综复杂的子系统关系封装起来,然后提供一个简单的接口给客户使用,就类似于一个转接口,可以想象成一个漏 斗,中间细的那一段,越细耦合度越低,外观模式就是为了降低耦合度。

三、代码

代理模式,代理者保存一个被代理的一个对象;适配器模式,保存了一个被适配的对象;而外观模式,就保存了各个子系统对象,然后根据实际逻辑组合。

 

八. Composite模式

将对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性.

九. Decorator模式

装饰是在原有类上增加功能用的
代理是对原有类作限制用的(例如权限,进行限制)。
机制差不多,但语义上方向相反

package sd;

/**
 * 项目
 */
interface Project {
	/**
	 * 写代码
	 */
	void doCoding();
}

/**
 * 代码工人
 */
class Employe implements Project {
	/**
	 * 编码
	 */
	public void doCoding() {
		System.out.println("代码工人 在编写代码,加班编啊编啊,终于编完了!");
	}
}

/**
 * 项目经理
 */
class Manager implements Project {
	private Project project; // 实际上存放的是代码工人对象

	public Manager(Project project) {
		this.project = project;
	}

	/**
	 * 编码
	 */
	public void doCoding() {
		// 项目经理开始新的工作
		startNewWork();
	}

	/**
	 * 模板:定义项目经理自己的事情
	 */
	public void startNewWork() {
		// 项目经理在做早期工作
		doEarlyWork();
		// 项目经理很牛,做完需求和设计后,直接将编码委派给代码工人干
		project.doCoding();
		// 项目经理在做收尾工作
		doEndWork();
	}

	/**
	 * 项目经理自己的事情:做早期工作
	 */
	public void doEarlyWork() {
	}

	/**
	 * 项目经理做收尾工作
	 */
	public void doEndWork() {
	}
}

/**
 * 具体的项目经理A
 */
class ManagerA extends Manager {

	public ManagerA(Project project) {
		super(project);
	}

	/**
	 * 项目经理自己的事情:做早期工作
	 */
	public void doEarlyWork() {
		System.out.println("项目经理A 在做需求分析");
		System.out.println("项目经理A 在做架构设计");
		System.out.println("项目经理A 在做详细设计");
	}
}

/**
 * 具体的项目经理B
 */
class ManagerB extends Manager {

	public ManagerB(Project project) {
		super(project);
	}

	/**
	 * 项目经理自己的事情:做早期工作
	 */
	public void doEarlyWork() {
		System.out.println("项目经理B 在做需求分析");
		System.out.println("项目经理B 在做详细设计");
	}

	/**
	 * 项目经理做收尾工作
	 */
	public void doEndWork() {
		System.out.println("项目经理B 在做收尾工作");
	}
}

/**
 * 客户端测试
 */
public class Client {
	public static void main(String args[]) {
		Project employe = new Employe(); // 代码工人
		Project managerA = new ManagerA(employe); // 项目经理
		Project managerB = new ManagerB(employe); // 项目经理
		// 以经理的名义将编码完成,功劳都是经理的,实际编码的是工人
		managerA.doCoding();
		managerB.doCoding();
	}
}
 

 

行为模式:

 

Memento(备忘机制):

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

/*
 * 发起人角色
 */
class Originator {
	private String state;

	/**
	 * 工厂方法,返回一个新的备忘录对象
	 */
	public Memento createMemento() {
		return new Memento(state);
	}

	/**
	 * 将发起人恢复到备忘录对象所记载的状态
	 */
	public void restoreMemento(Memento memento) {
		this.state = memento.getState();
	}

	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
	}
}

/*
 * 备忘录角色
 */
class Memento {
	private String state;

	/**
	 * 构造函数
	 */
	public Memento(String state) {
		this.state = state;
	}

	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
	}
}

/*
 * 负责人角色
 */
class Caretaker {
	private Memento memento;

	/**
	 * 备忘录的取值方法
	 */
	public Memento retrieveMemento() {
		return this.memento;
	}

	/**
	 * 备忘录的保存方法
	 */
	public void saveMemento(Memento memento) {
		this.memento = memento;
	}
}

/*
 * 客户端模拟实现
 */
public class Client {
	private static Originator ori = new Originator();
	private static Caretaker taker = new Caretaker();

	public static void main(String[] args) {
		// amigo当前的状态
		ori.setState("不爱打扮,做事拖拖拉拉,十足马大哈");
		// 保存amigo当前的状态
		taker.saveMemento(ori.createMemento());

		// mother要对amigo进行改造
		ori.setState("穿着时髦,做事精练");

		// mother发现改造后产生了很多副作用,于是反悔了,要恢复女儿以前的样子
		ori.restoreMemento(taker.retrieveMemento());

		// amigo被打回原型,^_^
		System.out.println("amigo当前情况: " + ori.getState());
	}
}

 

 观察者模式:

Observer模式定义对象间的一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。JDK里提供的Observer设计模式的实现由java.util.Observable类和 java.util.Observer接口组成。从名字上可以清楚的看出两者在Observer设计模式中分别扮演的角色:Observer是观察者角色,Observable是被观察目标(subject)角色。

import java.util.*;

/**
 * <p>
 * 使用Observer模式的例子。 自己的手机号码更改后,自己的朋友自动得到通知。
 * </p>
 * 
 * @version 1.0
 */
public class ObserverDesignPattern extends Observable {
	public ObserverDesignPattern() {
		super();
		// 有两个朋友
		addFriend(new Friend("Tom"));
		addFriend(new Friend("Jerry"));
	}

	public void addFriend(Friend n) {
		super.addObserver(n);
	}

	/**
	 * 手机号码改变
	 */
	public void modifyPhoneNumber(final long l) {
		/**
		 * 表明状态已经改变,不调用不会通知观察者
		 */
		setChanged();
		// 通知其他人自己的号码改变
		notifyObservers(new Long(l));
	}

	public static void main(String[] args) {
		ObserverDesignPattern op = new ObserverDesignPattern();
		// 更改手机号码
		System.out.println("我手机号码更改为13516816888!");
		op.modifyPhoneNumber(Long.parseLong("13516816888"));
	}
}

class Friend implements Observer {
	private String name;

	/**
	 * 朋友的姓名
	 */
	public Friend(String name) {
		this.name = name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void update(Observable o, Object arg) {
		if (arg instanceof Long) {
			System.out.println(name + "已经知道你的手机号码改为:" + arg);
		}
	}
}

Chain of Responsibility(职责链):

Chain of Responsibility(CoR) 是用一系列类(classes)试图处理一个请求request,这些类之间是一个松散的耦合,唯一共同点是在他们之间传递request. 也就是说,来了一个请求,A类先处理,如果没有处理,就传递到B类处理,如果没有处理,就传递到C类处理,就这样象一个链条(chain)一样传递下去。

public class Test {
	public static void main(String[] args) {
		Manager aManager = new Manager();
		ProjectManager aPM = new ProjectManager();
		Programmer aProgrammer = new Programmer();
		QA aQA = new QA();
		Others others = new Others();

		aManager.addChain(aPM);
		aPM.addChain(aProgrammer);
		aProgrammer.addChain(aQA);
		aQA.addChain(others);

		aManager.sendToChain("Get Project");
		aManager.sendToChain("Design");
		aManager.sendToChain("Coding");
		aManager.sendToChain("Test");
		aManager.sendToChain("Kill La Deng !");
	}
}

interface Chain {
	public abstract void addChain(Chain c);

	public abstract void sendToChain(String mesg);

	public abstract Chain getChain();
}

class Manager implements Chain {
	private Chain nextChain = null;
	private String responsibility = "Get Project";;

	public Manager() {
	}

	public void addChain(Chain c) {
		nextChain = c;
	}

	public Chain getChain() {
		return nextChain;
	}

	public void sendToChain(String mesg) {
		if (mesg.equals(responsibility)) {
			System.out.println("A manager  -->  Get a Project");
		} else {
			if (nextChain != null) {
				nextChain.sendToChain(mesg);
			}
		}
	}

}

class ProjectManager implements Chain {
	private Chain nextChain = null;
	private String responsibility = "Design";

	public ProjectManager() {
	}

	public void addChain(Chain c) {
		nextChain = c;
	}

	public Chain getChain() {
		return nextChain;
	}

	public void sendToChain(String mesg) {
		if (mesg.equals(responsibility)) {
			System.out.println("A PM  -->  Design");
		} else {
			if (nextChain != null) {
				nextChain.sendToChain(mesg);
			}
		}
	}

}

class Programmer implements Chain {
	private Chain nextChain = null;
	private String responsibility = "Coding";

	public Programmer() {
	}

	public void addChain(Chain c) {
		nextChain = c;
	}

	public Chain getChain() {
		return nextChain;
	}

	public void sendToChain(String mesg) {
		if (mesg.equals(responsibility)) {
			System.out.println("A Programmer  -->  Coding");
		} else {
			if (nextChain != null) {
				nextChain.sendToChain(mesg);
			}
		}
	}

}

class QA implements Chain {
	private Chain nextChain = null;
	private String responsibility = "Test";

	public QA() {
	}

	public void addChain(Chain c) {
		nextChain = c;
	}

	public Chain getChain() {
		return nextChain;
	}

	public void sendToChain(String mesg) {
		if (mesg.equals(responsibility)) {
			System.out.println("A QA  -->  Test");
		} else {
			if (nextChain != null) {
				nextChain.sendToChain(mesg);
			}
		}
	}

}

class Others implements Chain {
	private Chain nextChain = null;
	private String responsibility = "";

	public Others() {
	}

	public void addChain(Chain c) {
		nextChain = c;
	}

	public Chain getChain() {
		return nextChain;
	}

	public void sendToChain(String mesg) {
		if (mesg.equals(responsibility)) {
		} else
			System.out.println("No one can handle -->  " + mesg);
	}

}

 

Command:

将这些命令封装成在一个类中,然后用户再对这个类进行操作,这就是Command模式。

Facade(外观)模式似乎比较相似。

 

Mediator(中介者):

各个对象之间的交互操作非常多;每个对象的行为操作都依赖彼此对方,修改一个对象的行为,同时会涉及到修改很多其他对象的行为,如果使用Mediator模式,可以使各个对象间的耦合松散,只需关心和 Mediator的关系,使多对多的关系变成了一对多的关系,可以降低系统的复杂性,提高可修改扩展性.

package t;

class Anchor {
	private boolean free;
	private Mediator med;

	public Anchor(Mediator md) {
		med = md;
	}

	public boolean isFree() {
		return free;
	}

	public void setFree(boolean free) {
		this.free = free;
	}

	public void speak() {
		med.anchorSpeak();
	}

	public void stop() {
		med.anchorStop();
	}
}

class Guest {
	private boolean free;
	private Mediator med;

	public Guest(Mediator md) {
		this.med = md;
	}

	public boolean isFree() {
		return free;
	}

	public void setFree(boolean free) {
		this.free = free;
	}

	public void speak() {
		med.guestSpeak();

	}

	public void stop() {
		med.guestStop();
	}
}

class Mediator {
	private Anchor anchor;
	private Guest guest;

	public void regAnchor(Anchor anchor) {
		this.anchor = anchor;
	}

	public void regGuest(Guest guest) {
		this.guest = guest;
	}

	public void anchorSpeak() {
		if (!guest.isFree()) {
			guest.stop();
		}
		System.out.println("Anchor is speaking....");
		anchor.setFree(false);
	}

	public void guestSpeak() {
		if (anchor.isFree()) {
			System.out.println("Guest is speaking....");
			guest.setFree(false);
		} else {
			System.out.println("Anchor is speaking. Do not interrupt...");
		}

	}

	public void anchorStop() {
		System.out.println("Anchor stop speaking now....");
		anchor.setFree(true);
	}

	public void guestStop() {
		System.out.println("Guest stop speaking now...");
		guest.setFree(true);
	}
}

public class Demo {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Mediator med = new Mediator();
		Anchor anchor = new Anchor(med);
		Guest guest = new Guest(med);
		med.regAnchor(anchor);
		med.regGuest(guest);
		anchor.speak();
		guest.speak();
		anchor.stop();
		guest.speak();
		anchor.speak();
	}
}

Interpreter(解释器):

 

 

定义语言的文法 ,并且建立一个解释器来解释该语言中的句子.

 

Interpreter似乎使用面不是很广,它描述了一个语言解释器是如何构成的,在实际应用中,我们可能很少去构造一个语言的文法.我们还是来简单的了解一下, 看代码:

import java.util.HashMap;
import java.util.Map;

/**
 * Interpreter(解释器)
 */
public class Test {
	public static void main(String[] args) {
		// Test :
		// (true and x) and (y and (not x))
		Context context = new Context();

		VariableExp x = new VariableExp("X");
		VariableExp y = new VariableExp("Y");
		VariableExp bTure = new VariableExp("true");
		VariableExp bFalse = new VariableExp("false");

		// 规则
		context.Assign("true", true);
		context.Assign("false", false);
		context.Assign("X", false);
		context.Assign("Y", true);

		// (true and x) and (y and (not x))
//		BooleanExp expression = new AndExp(new AndExp(bTure, x), new AndExp(y, new NotExp(x)));
		// (y and (not x)) and (true and x)
		BooleanExp expression = new AndExp(new AndExp(y, new NotExp(x)), new AndExp(bTure, x));
		boolean result = expression.Evaluate(context);
		System.out.println("The result is:" + result);
	}
}

class Context {
	private Map<String, Boolean> context = new HashMap<String, Boolean>();

	public void Assign(String name, boolean val) {
		context.put(name, new Boolean(val));
	}

	public boolean LookUp(String name) {
		return ((Boolean) context.get(name)).booleanValue();
	}

	public Context() {
	}
}

interface BooleanExp {
	public abstract boolean Evaluate(Context c);

	public abstract BooleanExp Replace(String var, BooleanExp exp);

	public abstract BooleanExp Copy();
}

class VariableExp implements BooleanExp {
	private String name;

	public VariableExp(String _name) {
		name = _name;
	}

	public boolean Evaluate(Context c) {
		return c.LookUp(name);
	}

	public BooleanExp Copy() {
		return new VariableExp(name);
	}

	public BooleanExp Replace(String var, BooleanExp exp) {
		if (var.equals(name)) {
			return exp.Copy();
		} else {
			return new VariableExp(name);
		}
	}

}

class AndExp implements BooleanExp {
	private BooleanExp operand1;
	private BooleanExp operand2;

	public AndExp(BooleanExp oper1, BooleanExp oper2) {
		operand1 = oper1;
		operand2 = oper2;
	}

	public boolean Evaluate(Context c) {
		return operand1.Evaluate(c) && operand2.Evaluate(c);
	}

	public BooleanExp Copy() {
		return new AndExp(operand1.Copy(), operand2.Copy());
	}

	public BooleanExp Replace(String var, BooleanExp exp) {
		return new AndExp(operand1.Replace(var, exp), operand2.Replace(var, exp));
	}
}

class NotExp implements BooleanExp {
	private BooleanExp opernot1;

	public NotExp(BooleanExp oper1) {
		opernot1 = oper1;
	}

	public boolean Evaluate(Context c) {
		return !(opernot1.Evaluate(c));
	}

	public BooleanExp Copy() {
		return new NotExp(opernot1.Copy());
	}

	public BooleanExp Replace(String var, BooleanExp exp) {
		return new NotExp(opernot1.Replace(var, exp));
	}
}

 

Visitor模式:

作用于某个对象群中各个对象的操作. 它可以使你在不改变这些对象本身的情况下,定义作用于这些对象的新操作.

Visitor模式实际上是分离了collection结构中的元素和对这些元素进行操作的行为.

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

class Visitor {
	public void process(Saving service) {
		System.out.println("存款");
	}

	public void process(Draw service) {
		System.out.println("提款");
	}

	public void process(Fund service) {
		System.out.println("基金");
	}
}

// 定义业务基类。
abstract class Service {
	public abstract void accept(Visitor visitor);
}

// 不同的业务类。
class Saving extends Service {
	public void accept(Visitor visitor) {
		visitor.process(this);
	}
}

class Draw extends Service {
	public void accept(Visitor visitor) {
		visitor.process(this);
	}
}

class Fund extends Service {
	public void accept(Visitor visitor) {
		visitor.process(this);
	}
}

public class Client {
	public static void main(String[] args) {
		// 定义一个用户
		Visitor visitor = new Visitor();

		// 定义三个服务
		Service s1 = new Saving();
		Service s2 = new Draw();
		Service s3 = new Fund();

		// 一个用户需要受理如下业务。
/*
		s1.accept(visitor);
		s2.accept(visitor);
		s3.accept(visitor);
*/
		List<Service> services = new ArrayList<Service>();
		services.add(s1);
		services.add(s2);
		services.add(s3);

		Iterator<Service> iterator = services.iterator();
		while (iterator.hasNext()) {
			Service service = iterator.next();
			service.accept(visitor);
		}
	}
}
 

 

 

 

。。。