设计模式

23种设计模式

策略模式

策略模式(Strategy):它定义了算法家庭,分别封装起来,让他们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。

在这里插入图片描述

Strategy类,定义所有支持的算法的公共接口

//抽象算法类
abstract class Strategy{
	//算法方法
	public abstract void algorithmInterface();
}

ConcreteStrategy,封装了具体的算法或行为,继承于Strategy

//具体算法A
class ConcreteStrategyA extends Strategy{
	//算法A实现方法
	@Override
	public void algorithmInterface(){
		System.out.println("算法A实现");
	}
}
//具体算法B
class ConcreteStrategyB extends Strategy{
	//算法B实现方法
	@Override
	public void algorithmInterface(){
		System.out.println("算法B实现");
	}
}
//具体算法C
class ConcreteStrategyC extends Strategy{
	//算法C实现方法
	@Override
	public void algorithmInterface(){
		System.out.println("算法C实现");
	}
}

Context,用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用

//上下文
class Context{
	Strategy strategy;
	public Context(Strategy strategy){ //初始化时,传入具体的策略对象
		this.strategy = strategy;
	}
	//上下文接口
	public void contextInterface(){ //根据具体的策略对象,调用其算法的方法
	 	strategy.algorithmInterface();
	}
}

客户端代码

public static void main(String[] args){
	Context context;

	//由于实例化不同的策略,所以最终在调用context.ContextInterface();时,所获得的结果也就不尽相同
	context = new Context(new ConcreteStrategyA());
	context.contextInterface();
	
	context = new Context(new ConcreteStrategyA());
	context.contextInterface();
	
	context = new Context(new ConcreteStrategyA());
	context.contextInterface();
}

装饰模式

装饰模式(Decorator),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活

在这里插入图片描述
Component类

abstract class Component{
	public abstract void operation();
}

ConcreteComponent类

class ConcreteComponent extends Component{
	@Override
	public void operation(){
		System.out.println("具体对象的操作");
	}
}

Decorator类

abstract class Decorator extends Component{
	protected Component component;
	
	public void setComponent(Component component){ //设置Component
		this.component = component;
	}
	
	public override void operation(){ //重写Operation(),实际执行的是Component的Operation();
		if(component != null){
			component.operation();
		}
	}
}

ConcreteDecoratorA类

class ConcreteDecoratorA extends Decorator{
	private String addedState; //本类的独有功能,以区别于ConcreteDecoratorB
	
	@Override
	public void Operation(){
		super.operation();//首先运行原Component的Operation(),再执行本类的功能,如addedState,相当于对原Component进行了装饰
		addedState = "New State";
		System.out.println("具体装饰对象A的操作");
	}
}

class ConcreteDecoratorB extends Decorator{
	private String addedState;

	@Override
	public void operation(){
		super.operation();//首先运行原Component的operation(),再执行本类的功能,如addedBehavior(),相当于对原Component进行了装饰
		addedBehavior();
		System.out.println("具体装饰对象B的操作");
	}

	private void addedBehavior(){//本类特有的方法,以区别于ConcreteDecoratorA
	}
}

客户端代码

public static void Main(String[] args){
	ConcreteComponent c = new ConcreteComponent();
	ConcreteDecoratorA d1 = new ConcreteDecoratorA();
	ConcreteDecoratorB d2 = new ConcreteDecoratorB();

	//装饰的方法是,首先用ConcreteComponent实例化对象c,然后用ConcreteDecoratorA的实例化对象d1来包装c,再用ConcreteDecoratorB的对象d2包装d1,最终执行d2的operation()
	d1.setComponent(c);
	d2.setComponent(d1);
	d2.operation();

	Console.Read();
}

在这里插入图片描述

代理模式

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

在这里插入图片描述

Subject类,定义了RealSubject和Proxy的公用接口,这样就在任何使用RealSubject的地方都可以使用Proxy。

abstract class Subject{
	public abstract void request();
}

RealSubject类,定义Proxy代表的真实实体

class RealSubject extends Subject{

	@Override
	public void request(){
		System.out.println("真实的请求");
	}
}

Proxy类,保存一个引用使得代理可以访问实体,并提供一个与Subject接口相同的接口,这样代理就可以用来代替实体

class Proxy extends Subject{
	RealSubject realSubject;
	
	@Override
	public void request(){
		if(realSubject == null){
			realSubject = new RealSubject();
		}
		realSubject.request();
	}
}

客户端代码

public static void main(String[] args){
	Proxy proxy = new Proxy();
	proxy.request();
	
	Console.Read();
}

工厂方法模式

工厂方法模式(Factory Method),定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类

在这里插入图片描述

原型模式

原型模式(Prototype),用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

在这里插入图片描述

原型类

abstract class Prototype{
	private String id;

	public Prototype(String id){
		this.id = id;
	}

	public String getId(){
		return id;
	}

	public abstract Prototype Clone();//抽象类关键就是有这样一个Clone方法
}

具体原型类

class ConcretePrototype1 extends Prototype{
	public ConcretePrototype1(String id){
		super.id;
	}
	
	@Override
	public Prototype Clone(){

		/*
		创建当前对象的浅表副本。方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。
		如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;
		因此,原始对象及其副本引用同一个对象。
		*/
		return (Prototype)this.memberwiseClone();
	}
}

客户端代码

public static void main(String[] args){
	ConcretePrototype1 p1 = new ConcretePrototype1("I");
	ConcretePrototype c1 = (ConcretePrototype1)p1.clone();//克隆类ConcretePrototype1的对象p1就能得到新的实例c1
	System.out.println("Cloned:{0}",c1.getId);

	Console.Read();
}

模板方法模式

模板方法模式,定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤

在这里插入图片描述
AbstractClass是抽象类,其实也就是一抽象模板,定义并实现了一个模板方法。这个模板方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法

abstract class AbstractClass{

	//一些抽象行为,放到子类去实现
	public abstract void primitiveOperation1();
	public abstract void primitiveOperation2();

	//模板方法,给出了逻辑的骨架,而逻辑的组成是一些响应的抽象操作,它们都推迟到子类实现
	public void templateMethod(){
		primitiveOperation1();
		primitiveOperation2();
		System.out.println("");
	}
}

ConcreteClass,实现父类所定义的一个或多个抽象方法。每一个AbstractClass都可以有任意多个ConcreteClass与之对应,而每一个ConcreteClass都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不同实现,从而使得顶级逻辑的实现各不相同。

class ConcreteClassA extends AbstractClass{

	@Override
	public void primitiveOperation1(){
		System.out.println("具体类A方法1实现");//与ConcreteClassB不同的方法实现
	}

	@Override
	public void primitiveOperation2(){
		System.out.println("具体类A方法2实现");
	}
}

class ConcreteClassB extends AbstractClass{

	@Override
	public void primitiveOperation1(){
		System.out.println("具体类B方法1实现");//与ConcreteClassA不同的方法实现
	}

	@Override
	public void primitiveOperation2(){
		System.out.println("具体类B方法2实现");
	}
}

客户端调用

public static void main(String[] args){
	AbstractClass c;

	c = new ConcreteClassA();
	c.templateMethod();

	c = new ConcreteClassB();
	c.templateMethod();

	Console.Read();
}

外观模式

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

在这里插入图片描述

四个子系统的类

class SubSystemOne{
	public void MethodOne(){
		System.out.println("子系统方法一");
	}
}

class SubSystemTwo(){
	public void MethodTwo(){
		System.out.println("子系统方法二");
	}
}

class SubSystemThree(){
	public void MethodThree(){
		System.out.println("子系统方法三");
	}
}

class SubSystemFour(){
	public void MethodFour(){
		System.out.println("子系统方法四");
	}
}

外观类

class Facade{//外观类,它需要了解所有的子系统的方法或属性,进行组合,以备外界调用
	SubSystemOne one;
	SubSystemTwo two;
	SubSystemThree three;
	SubSystemFour four;

	public Facade(){
		one = new SubSystemOne();
		two = new SubSysemTwo();
		three = new SubSystemThree();
		four = new SubSystemFour();
	}

	public void methodA(){
		System.out.println("\n方法组A()----");
		one.methodOne();
		two.methodTwo();
		four.methodFour();
	}

	public void methodB(){
		System.out.println("\n方法组B()----");
		two.methodTwo();
		three.methodThree();
	}
}

客户端调用

public static void main(String[] args){
	Facade facade = new Facade();

	facade.methodA();
	facade.methodB();
}

建造者模式

建造者模式(Builder),将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建出不同的表示

在这里插入图片描述

Product类-产品类,由多个部件组成

class Product{
	IList<String> parts = new List<String>();

	public void add(String part){//添加产品部件
		parts.add(part);
	}
	
	public void show(){
		System.out.println("\n产品 创建----");
			foreach(String part : parts){//列举所有的产品部件
				System.out.println(part);
			}
		}
}

Builder类——抽象建造者类,确定产品由两个部件PartA和PartB组成,并声明一个得到产品建造后结果的方法GetResult

abstract class Builder{
	public abstract void buildPartA();
	public abstract void buildPartB();
	public abstract Product GetResult();

ConcreteBuilder1类——具体建造者类

class ConcreteBuilder1 extends Builder{
	private Product product = new Product();

	@Override
	public void buildPartA(){
		product.add("部件A");
	}

	@Override
	public void buildPartB(){
		product.add("部件B");
	}

	@Override
	public Product getResult(){
		return product;
	}
}

ConcreteBuilder2类——具体建造者类

class ConcreteBuilder2 extends Builder{
	private Product product = new Product();
	
	//建造具体的两个部件是部件X和部件Y
	@Override
	public void buildPartA(){
		product.add("部件X");
	}

	@Override
	public void buildPartB(){
		product.add("部件Y");
	}

	@Override
	public Product getResult(){
		return product;
	}
}

Director类——指挥者类

class Director{
	public void construct(Builder builder){
		//用来指挥建造过程
		builder.builderPartA();
		builder.builderPartB();
	}
}

客户端代码,客户不需知道具体的建造过程

public static void Main(String[] args){
	Director director = new Director();
	Builder b1 = new ConcreteBuilder1();
	Builder b2 = new ConcreteBuilder2();
	
	//指挥者用ConcreteBuilder1的方法来建造产品
	direcot.construct(b1);
	Product p1 = b1.getResult();
	p1.show();

	//指挥者用ConcreteBuilder2的方法来建造产品
	direcot.construct(b2);
	Product p2 = b2.getResult();
	p2.show();

	Console.Read();
}

观察者模式(发布-订阅模式)

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

在这里插入图片描述

Subject类,可翻译为主题或抽象通知者,一般用一个抽象类或者一个接口实现。它把所有对观察者对象的引用保存在一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象

abstract class Subject{
	private IList<Observer> Observers = new List<Observer>();

	//增加观察者
	public void attach(Observer observer){
		observers.add(observer);
	}
	//移出观察者
	public void detach(Observer observer){
		observers.remove(observer);
	}
	//通知
	public void notify(){
		foreach(Observer o : observers){
			o.update();
		}
	}
}

Observer类,抽象观察类,为所有的具体观察者定义一个接口,在得到主题的通知时更新自己。这个接口叫做更新接口。抽象观察者一般用一个抽象类或者一个接口实现。更新接口通常包含一个update()方法,这个方法叫做更新方法

abstract class Observer{
	public abstract void update();
}

ConcreteSubject类,叫做具体主题或具体通知者,将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个具体子类实现。

class ConcreteSubject extends Subject{
	private String subjectState;
	//具体被观察者状态
	public String getSubjectState{
		return subjectState;
	}
	public void setSubjectState(String subjectState){
		this.subjectState = subjectState;
	}
}

ConcreteObserver类,具体观察者,实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。具体观察者角色可以保存一个指向具体主题对象的引用。具体观察者角色通常用一个具体子类实现

class ConcreteObserver extends Observer{
	private String name; 
	private String observerState;
	private ConcreteSubject subject;
	
	public ConcreteObserver(ConcreteSubject subject,String name){
		this.subject = subject;
		this.name = name;
	}
	
	@Override
	public void update(){
		observerState = subject.subjectState;
		System.out.println("观察者{0}的新状态是{1}",name,observerState);
	}
	
	public ConcreteSubject getSubject{
		return subject;
	}
	public void setSubject(ConcreteSubject subject){
		this.subject = subject;
	}
}

客户端代码

public static void main(String[] args){
	ConcreteSubject s = new ConcreteSubject();
	
	s.attach(new ConcreteObserver(s,"X"));
	s.attach(new ConcreteObserver(s,"Y"));
	s.attach(new ConcreteObserver(s,"Z"));

	s.subjectState = "ABC";
	s.notify();

	Console.Read();
}

抽象工厂模式

抽象工厂模式(Abstract Factory),提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
在这里插入图片描述

状态模式

状态模式(State),当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

在这里插入图片描述

State类,抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为

abstract class State{
	public abstract void handle(Context context);
}

ConcreteState类,具体状态,每一个子类实现一个与Context的一个状态相关的行为

class ConcreteStateA extends State{
	@Override
	public void handle(Context context){
		context.State = new ConcreteStateB();//设置ConcreteStateA的下一状态是ConcreteStateB
	}
}

class ConcreteStateB extends State{
	@Override
	public void handle(Context context){
		context.State = new ConcreteStateA();//设置ConcreteStateA的下一状态是ConcreteStateA
	}
}

Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态。

class Context{
	private State state;
	public Context(State state){//定义Context的初始状态
		this.state = state;
	}
	
	//可读写的状态属性,用于读取当前状态和设置新状态
	public State getState(){
		return state;
	}
	public void setState(State state){
		this.state = state;
		System.out.println("当前状态:"+state.getType().Name);
	}
	
	public void request(){
		state.handle(this);//对请求做处理,并设置下一状态
	}
}

客户端代码

public static void main(String[] args){
	Context c = new Context(new ConcreteStateA());//设置Context的初始状态为ContextStateA
	
	//不断的请求,同时更改状态
	c.request();
	c.request();
	c.request();
	c.request();
	
	Console.Read();
}

适配器模式

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

在这里插入图片描述

Target(这是客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口)

class Target{
	public virtual void request(){
		System.out.println("普通请求!");
	}
}

Adaptee(需要适配的类)

class Adaptee{
	public void specificRequest(){
		System.out.println("特殊请求!");
	}
}

Adapter(通过在内部包装一个Adaptee对象,把源接口转换成目标接口)

class Adapter extends Target{
	private Adaptee adaptee = new Adaptee();//建立一个私有的Adaptee对象
	
	@Override
	public void request(){
		adaptee.specificRequest();//这样就可以把表面上调用request()方法变成实际调用specificRequest()
	}
}

客户端代码

public static void main(String[] args){
	//对客户端来说,调用的就是Target的Request()
	Target target = new Adapter();
	target.request();

	Console.Read();
}

备忘录模式

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

在这里插入图片描述

发起人(Originator)类

class Originator{
	//需要保存的属性,可能有多个
	private String state;
	public String getState{
		return state;
	}
	public void setState(String state){
		this.state = state;
	}
	//创建备忘录,将当前需要保存的信息导入并实例化出一个Memento对象
	public Memento createMemento(){
		return (new Memento(state));
	//创建备忘录,将Memento导入并将相关数据恢复
	public void setMemento(Memento memento){
	 	state = memento.getState();
	 }
	 //显示数据
	public void show(){
		System.out.println("State="+state);
	}
}

备忘录(Memento)类

class Memento{
	private String state;
	
	//构造方法,将相关数据导入
	public Memento(String state){
		this.state = state;
	}
	
	public String getState(){
		return state;//需要保存的数据,可以是多个
	}
}

管理者(Caretaker)类

class Caretaker{
	private Memento memento;
	//得到或设置备忘录
	public Memento getMemento(){
		return memento;
	}
	public void setMemento(Memento memento){
		this.memento = memento;
	}
}

客户端程序

public static void Main(String[] args){
	//Originator初始状态,状态属性为“On”
	Originator o = new Originator();
	o.setState("On");
	o.show();
	
	//保存状态时,由于有了很好的封装,可以隐藏Originator的实现细节
	Caretaker c = new Caretaker();
	c.setMemento(o.createMemento());
	
	//Originator改变了状态属性为“Off”
	o.setState("Off");
	o.show();

	//恢复原初始状态
	o.setMemento(c.getMemento());
	o.show();

	Console.Read();
}

组合模式

组合模式(Composite),将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

在这里插入图片描述

Component为组合中的对象声明接口,在适当情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component的子部件。

abstract class Component{
	protected String name;
	
	public Component(String name){
		this.name = name;
	}
	
	//通常都用add和remove方法来提供增加或移除树叶或树枝的功能
	public abstract void add(Component c);
	public abstract void remove(Component c);
	public abstract void display(int depth);
}

Leaf在组合中表示叶节点对象,叶节点没有子节点。

class Lead extends Component{
	public Leaf(String name){
		super.name;
	}
	
	/*由于叶子没有再增加分枝和树叶,所有add和remove方法实现它没有意义,
	但这样做可以消除叶节点和枝节点对象在抽象层次的区别,他们具备完全一致的接口
	*/
	@Override
	public void add(Component c){
		System.out.println("Cannot add to a leaf");
	}
	
	@Override
	public void remove(Component c){
		System.out.println("Cannot remove from a leaf");
	}
	
	@Override
	public void display(int depth){
		//叶节点的具体方法,此处是显示其名称和级别
		System.out.println(new String('-',depth)+name);
	}
}

Composite定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关的操作,比如增加add和删除remove

class Composite extends Component{
	private List<Component> children = new List<Component>();//一个子对象集合用来存储其下属的枝节点和叶节点
	public Composite(String name){
		super.name;
	}
	
	@Override
	public void add(Component c){
		children.add(c);
	}
	
	@Override
	public void remove(Component c){
		children.remove(c);
	}
	
	@Override
	public void display(int depth){
		//显示其枝节点名称,并对其下级进行遍历
		System.out.println(new String('-',depth)+name);
		
		foreach(Component component : children){
			component.display(depth + 2);
		}
	}
}

客户端代码,能通过Component接口操作组合部件的对象

public static void Main(String[] args){
	//生成树根root,根上长出两叶LeafA和LeafB
	Composite root = new Composite("root");
	root.add(new Leaf("Leaf A"));
	root.add(new Leaf("Leaf B"));
	
	//根上长出分枝CompositeX,分枝上也有两叶LeafXA和LeafXB
	Composite comp = new Composite("Composite X");
	comp.add(new Leaf("Leaf XA"));
	comp.add(new Leaf("Leaf XB"));
	
	root.add(comp);
	
	//在CompositeX上再长出分枝CompositeXY,分枝上也有两叶LeafXYA和LeafXYB
	Composite comp2 = new Composite("Composite XY");
	comp2.add(new Leaf("Leaf XYA"));
	comp2.add(new Leaf("Leaf XYB"));
	
	comp.add(comp2);
	
	root.add(new Leaf("Leaf C"));
	
	//根部又长出两叶LeafC和LeafD,可惜LeafD没长牢,被风吹走了
	Leaf leaf = new Leaf("Leaf D");
	root.add(leaf);
	root.remove(leaf);
	
	//显示大树的样子
	root.display(1);
	
	Console.Read();
}

迭代器模式

迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。

在这里插入图片描述

Iterator迭代器抽象类

abstract class Iterator{
	//用于定义得到开始对象、得到下一个对象、判断是否到结尾、当前对象等抽象方法,统一接口
	public abstract Object first();
	public abstract Object next();
	public abstract boolean isDone();
	public abstract Object currentItem();
}

Aggregate聚集抽象类

abstract class Aggregate(){
	public abstract Iterator createIterator();//创建迭代器
}

ConcreteIterator具体迭代器类,继承Iterator

class ConcreteIterator extends Iterator{
	private ConcreteAggregate aggregate;//定义了一个具体聚集对象
	private int current = 0;
	
	//初始化时将具体的聚集对象传入
	public ConcreteIterator(ConcreteAggregate aggregate){//初始化时将具体的聚集对象传入
		this.aggregate = aggregate;
	}
	
	@Override
	public Object first(){//得到聚集的第一个对象
		return aggregate[0];
	}
	
	@Override
	public Object next(){//得到聚集的下一个对象
		Object ret = null;
		current++;
		if(current < aggregate.getCount()){
			ret = aggregate[current];
		}
		return ret;
	}
	
	@Override
	public boolean isDone(){//判断当前是否遍历到结尾,到结尾返回true
		return current >= aggregate.getCount() ? true :false;
	}
	
	@Override
	public Object currentItem(){//返回当前的聚集对象
		return aggregate[current];
	}
}

ConcreteAggregate具体聚集类继承Aggregate

class ConcreteAggregate extends Aggregate{
	private IList<Object> items = new List<Object>();//声明一个IList泛型变量,用于存放聚合对象,用ArrayList同样可以实现
	public Iterator createIterator(){
		return new ConcreteIterator(this);
	}
	public int getCount(){//返回聚集总个数
		return items.Count;
	}
	public Object this[int index]{//声明一个索引器
		get {return items[index];}
		set {items.insert[index,value];}
	}
}

客户端代码

public static void Main(String[] args){
	ConcreteAggregate a = new ConcreteAggregate();//公交车,即聚集对象

	//新上来的乘客,即对象数组
	a[0] = "大鸟";
	a[1] = "小菜";
	a[2] = "行李";
	a[3] = "老外";
	a[4] = "公交内部成员";
	a[5] = "小偷";
	
	//售票员出场,先看好了上车的是哪些人,即声明了迭代器对象
	Iterator i = new ConcreteIterator(a);//从第一个乘客开始
	Object item = i.first();
	while(!i.isDone()){
		System.out.println("{0}请买车票!",i.currentItem());//对面前的乘客告知请买票
		i.next();//下一乘客
	}
	
	Console.Read();
}

单例模式

单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点

在这里插入图片描述

Singleton类,定义一个GetInstance操作,允许客户访问它的唯一实例。GetInstance是一个静态方法,主要负责创建自己的唯一实例

class Singleton{
	private static Singleton instance;
	
	private Singleton(){//构造方法让其private,这就堵死了外界利用new 创建此类实例的可能
	}
	
	public static Singleton getInstance(){//此方法是获得本类实例的唯一全局访问点
		if(instance == null){//若实例不存在,则new一个新实例,否则返回已有的实例
			instance = new Singleton();
		}
		return instance;
	}
}

客户端代码

public static void Main(String[] args){
	Singleton s1 = Singleton.getInstance();
	Singleton s2 = Singleton.getInstance();
	if(s1 == s2){//比较两次实例化后对象的结果是实例相同
		System.out.println("两个对象是相同的实例。");
	}
	
	Console.Read();
}

桥接模式

桥接模式(Bridge),将抽象部分与它的实现部分分离,使它们都可以独立地变化。

在这里插入图片描述

Implementor类

abstract class Implementor{
	public abstract void operation();
}

ConcreteImplementorA和ConcreteImplementorB等派生类

class ConcreteImplementorA extends Implementor{
	
	@Override
	public void operation(){
		System.out.println("具体实现A的方法执行");
	}
}

class ConcreteImplementorB extends Implementor{

	@Override
	public void operation(){
		System.out.println("具体实现B的方法执行");
	}
}

Abstraction类

class Abstraction{
	protected Implementor implementor;
	
	public void setImplementor(Implementor implementor){
		this.implementor = implementor;
	}
	
	public virtual void operation(){
		implementor.operation();
	}
}

RefinedAbstraction类

class RefinedAbstraction extends Abstraction{
	
	@Override
	public void operation(){
		implementor.operation();
	}
}

客户端实现

public static void Main(String[] args){
	Abstraction ab = new RefinedAbstraction();
	
	ab.setImplementor(new ConcreteImplementorA());
	ab.operation();
	
	ab.setImplementor(new ConcreteImplementorB());
	ab.operation();

	Console.Read();
}

命令模式

命令模式(Command),将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作

在这里插入图片描述

Command类,用来声明执行操作的接口

abstract class Command{
	protected Receiver receiver;
	
	public Command(Receiver receiver){
		this.receiver = receiver;
	}
	
	abstract public void execute();
}

ConcreteCommand类,将一个接收者对象绑定于一个动作,调用接收者相应的操作,以实现execute。

class ConcreteCommand extends Command{

	public ConcreteCommand(Receiver receiver){
		super.receiver;
	}
	
	@Override
	public void execute(){
		receiver.action();
	}
}

Invoker类,要求该命令执行这个请求

class Invoker{
	private Command command;
	
	public void setCommand(Command command){
		this.command = command;
	}
	
	public void executeCommand(){
		command.execute();
	}
}

Receiver类,知道如何实施与执行一个与请求无关的操作,任何类都可能作为一个接收者。

class Receiver{
	public void action(){
		System.out.println("执行请求!");
	}
}

客户端代码,创建一个具体命令对象并设定它的接收者

public static void Main(String[] args){
	Receiver r = new Receiver();
	Command c = new ConcreteCommand(r);
	Invoker i = new Invoker();
	
	i.setCommand(c);
	i.executeCommand();
	
	Console.Read();
}

职责链模式

职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止.

在这里插入图片描述

Handler类,定义一个处理请示的接口

abstract class Handler{
	protected Handler successor;
	
	public void setSuccessor(Handler successor){//设置继任者
		this.successor = successor;
	}
	
	public abstract void handleRequest(int request);//处理请求的抽象方法
}

ConcreteHandler类,具体处理者类,处理它所负责的请求,可访问它的后继者,如果可处理该请求,就处理之,否则就将该请求转发给它的后继者。
ConcreteHandler1,当请求数在0到10之间则有权处理,否则转到下一位。

class ConcreteHandler1 extends Handler{
	
	@Override
	public void HandleRequest(int request){//0到10,处理此请求
		if(request >= 0 && request <= 10){
			System.out.println("{0}处理请求{1}",this.getType().Name,request);
		}else if(successor != null){
			successor.handleRequest(request);//转移到下一位
		}
	}
}

ConcreteHandler2,当请求数在10到20之间则有权处理,否则转到下一位

class ConcreteHandler2 extends Handler{
	
	@Override
	public void HandleRequest(int request){
		if(request >= 10 && request <= 20){//10到20,处理此请求
			System.out.println("{0}处理请求{1}",this.getType().Name,request);
		}else if(successor != null){
			successor.handleRequest(request);//转移到下一位
		}
	}
}

ConcreteHandler3,当请求数在20到30之间则有权处理,否则转到下一位

class ConcreteHandler3 extends Handler{
	
	@Override
	public void HandleRequest(int request){
		if(request >= 20 && request <= 30){//20到30,处理此请求
			System.out.println("{0}处理请求{1}",this.getType().Name,request);
		}else if(successor != null){
			successor.handleRequest(request);//转移到下一位
		}
	}
}

客户端代码,向链上的具体处理者对象提交请求.

public static void Main(){
	Handler h1 = new ConcreteHandler1();
	Handler h2 = new ConcreteHandler2();
	Handler h3 = new ConcreteHandler3();
	//设置职责链上家与下家
	h1.setSuccessor(h2);
	h2.setSuccessor(h3);
	
	int[] requests = {2,5,14,22,18,3,27,20};
	
	//循环给最小处理者提交请求,不同的数额,由不同权限处理者处理
	foreach(int request : requests){
		h1.handleRequest(request);
	}
}

中介者模式

中介者模式(Mediator),用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使得耦合松散,而且可以独立地改变它们之间的交互

在这里插入图片描述

Mediator类 抽象中介者类

abstract class Mediator{
	//定义一个抽象的发送消息方法,得到同事对象和发送信息
	public abstract void send(String message,Colleague colleague);
}

Colleague类 抽象同事类

abstract class Colleague{
	protected Mediator mediator;
	public Colleague(Mediator mediator){//构造方法,得到中介者对象
		this.mediator = mediator;
	}
}

ConcreteMediator类 具体中介者类

class ConcreteMediator extends Mediator{
	private ConcreteColleague1 colleague1;
	private ConcreteColleague2 colleague2;
	
	//得到了解所有的具体同事对象
	public void  setColleague1(Colleague colleague){
	this.colleague1 = colleague;
	}
	
	public void setColleague2(Colleague colleague){
	this.colleague2 = colleague;
	}
	
	@Override
	public void send(String message,Colleague colleague){//重写发送信息的方法,根据对象作出选择判断,通知对象
		if(colleague == colleague1){
			colleague2.notify(message);
		}else{
			colleague1.notify(message);
		}
	}
}

ConcreteColleague1和ConcreteColleague2等各种同事对象

class ConcreteColleague1 extends Colleague{
	public ConcreteColleague1(Mediator mediator){
		super.mediator;
	}
	
	public void send(String message){
		mediator.send(message,this);//发送信息时通常是中介者发送出去的
	}
	
	public void notify(String message){
		System.out.println("同事1得到信息"+message);
	}
}

class ConcreteColleague2 extends Colleague{
	public ConcreteColleague2(Mediator mediator){
		super.mediator;
	}
	
	public void send(String message){
		mediator.send(message,this);
	}
	
	public void notify(String message){
		System.out.println("同事2得到信息"+message);
	}
}

客户端调用

public static void Main(String[] args){
	ConcreteMediator m = new ConcreteMediator();

	//让两个具体同事类认识中介者对象
	ConcreteColleague1 c1 = new ConcreteColleague1(m);
	ConcreteColleague2 c2 = new ConcreteColleague2(m);
	
	//让中介者认识各个具体同事类对象
	m.setColleague1(c1);
	m.setColleague2(c2);
	
	//具体同事类对象的发送信息都是通过中介者转发
	c1.send("吃饭了吗?");
	c2.send("没有呢,你打算请客吗?");
	
	Console.Read();
}

享元模式

享元模式(Flyweight),运用共享技术有效地支持大量细粒度的对象

在这里插入图片描述

Flyweight类,它是所有具体享元类的超类或接口,通过这个接口,Flyweight可以接受并作用于外部状态。

abstract class Flyweight{
 	public abstract void operation(int extrinsicstate);
}

ConcreteFlyweight是继承Flyweight超类或实现Flyweight接口,并为内部状态增加存储空间。

class ConcreteFlyweight extends Flyweight{
	
	@Override
	public void operation(int extrinsicstate){
		System.out.println("具体Flyweight:"+extrinsicstate);
	}
}

UnsharedConcreteFlyweight是指那些不需要共享的Flyweight子类。因为Flyweight接口共享成为可能,但它并不强制共享。

class UnsharedConcreteFlyweight extends Flyweight{
	
	@Override
	public void operation(int extrinsicstate){
		System.out.println("不共享的具体Flyweight:"+extrinsicstate);
	}
}

FlyweightFactory,是一个享元工厂,用来创建并管理Flyweight对象。它主要是用来确保合理地共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory对象提供一个已创建或者创建一个(如果不存在的话)

class FlyweightFactory{
	private Hashtable flyweights = new Hashtable();
	
	public FlyweightFactory(){
		//初始化工厂时,先生成三个实例
		flyweights.add("X",new ConcreteFlyweight());
		flyweights.add("Y",new ConcreteFlyweight());
		flyweights.add("Z",new ConcreteFlyweight());
	}
	
	public Flyweight getFlyweight(String key){
		//根据客户端请求,获得已生成的实例
		return ((Flyweight)flyweights[key]);
	}
}

客户端代码

public static void Main(String[] args){

	int extrinsicstate = 22;//代码外部状态
	
	FlyweightFactory f = new FlweightFactory();
	
	Flyweight fx = f.getFlyweight("X");
	fx.operation(--extrinsicstate);
	
	Flyweight fy = f.getFlyweight("Y");
	fy.operation(--extrinsicstate);
	
	Flyweight fz = f.getFlyweight("Z");
	fz.operation(--extrinsicstate);
	
	Flyweight uf = new UnsharedConcreteFlyweight();
	
	uf.operation(--extrinsticstate);
	
	Console.Read();
}

解释器模式

==解释器模式(interpreter),给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

在这里插入图片描述

AbstractExpression(抽象表达式),声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享。

abstract class AbstractExpression{
	public abstract void interpret(Context context);
}

TerminalExpression(终结符表达式),实现与文法中的终结符相关联的解释操作。实现抽象表达式中所要求的接口,主要是一个interpret()方法。文法中每一个终结符都具有一个具体终结符表达式与之相对应

class TerminalExpression extends AbstractExpression{

	@Override
	public void interpret(Context context){
		System.out.println("终端解释器");
	}
}

NonterminalExpression(非终结符表达式),为文法中的非终结符实现解释操作。对文法中每一个规则R1、R2…Rn都需要一个具体的非终结符表达式类。通过实现抽象表达式的interpret()方法实现解释操作。解释操作以递归方式调用上面所提到的代表R1、R2…Rn中各个符号的实例变量。

class NoterminalExpression extends AbstractExpression{
	
	@Override
	public void interpret(Context context){
		System.out.println("非终端解释器");
	}
}

Context,包含解释器之外的一些全局信息

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

客户端代码,构建表示该文法定义的语言中一个特定的句子的抽象语法树。调用解释操作

public static void Main(String[] args){
	Context context = new Context();
	IList<AbstractExpression> list = new List<AbstractExpression>();
	list.add(new TerminalExpression());
	list.add(new NoterminalExpression());
	list.add(new TerminalExpression());
	list.add(new TerminalExpression());
	
	foreach(AbstractExpression exp : list){
		exp.interpret(context);
	}
	
	Console.Read();
}

访问者模式

访问者模式(Visitor),表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

在这里插入图片描述

Visitor类,为该对象结构中ConcreteElement的每一个类声明一个Visit操作。

abstract class Visitor{
	public abstract void visitConcreteElementA(ConcreteElementA concreteElementA);
	
	public abstract void visitConcreteElementB(ConcreteElementB concreteElementB);
}

ConcreteVisitor1和ConcreteVisitor2类,具体访问者,实现每个由Visitor声明的操作。每个操作实现算法的一部分,而该算法片断乃是对应于结构中对象的类

class ConcreteVisitor1 extends Visitor{

	@Override
	public void visitConcreteElementA(ConcreteElementA concreteElementA){
		System.out.println("{0}被{1}访问",concreteElementA.getType().Name,this.getType().Name);
	}
	
	@Override
	public void visitConcreteElementB(ConcreteElementB concreteElementB){
		System.out.println("{0}被{1}访问",concreteElementB.getType().Name,this.getType().Name);
	}
}

class ConcreteVisitor2 extends Visitor{
	//代码与上类类似,省略
} 

Element类,定义一个Accept操作,它以一个访问者为参数

abstract class Element{
	public abstract void accept(Visitor visitor);
}

ConcreteElementA和ConcreteElementB类,具体元素,实现Accpet操作

class ConcreteElementA extends Element{
	@Override
	public void accept(Visitor visitor){
		visitor.visitConcreteElementA(this);
	}
	
	public void operationA(){
	}
}

class ConcreteElementB extends Element{
	@Override
	public void accept(Visitor visitor){
		visitor.visitConcreteElementB(this);
	}
	
	public void operationB(){
	}
}

ObjectStructure类,能枚举它的元素,可以提供一个高层的接口以允许访问者访问它的元素

class ObejctStructure{
	private IList<Element> elements = new List<Element>();
	
	public void attach(Element element){
		elements.add(element);
	}
	
	public void detach(Element element){
		elements.remove(element);
	}
	
	public void accept(Visitor visitor){
		foreach(Element e : elements){
			e.accpet(visitor);
		}
	}
}

客户端代码

public static void Main(String[] args){
	ObjectStructure o = new ObjectStructure();
	o.attach(new ConcreteElementA());
	o.attach(new ConcreteElementB());
	
	ConcreteVisitor1 v1 = new ConcreteVisitor1();
	ConcreteVisiotr2 v2 = new ConcreteVisitor2();
	
	o.accept(v1);
	o.accept(v2);

	Console.Read();
}

原则

单一职责原则

单一职责原则(SRP),就一个类而言,应该仅有一个引起它变化的原因

开放-封闭原则

开放-封闭原则,是说软件实体(类、模块、函数等等)应该可以扩展,但是不可修改。

依赖倒转原则

抽象不应该依赖细节,细节应该依赖于抽象。

里式代换原则

里式代换原则(LSP):子类型必须能够替代掉它们的父类型。

迪米特法则

迪米特法则,如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值