Java设计模式 原型模式 策略模式 观察者模式

原型模式

什么是原型模式

克隆
原型模式是一个创建型的模式。原型二字表明了改模式应该有一个样板实例,用户从这个样板对象中复制一个内部属性一致的对象,这个过程也就是我们称的“克隆”。被复制的实例就是我们所称的“原型”,这个原型是可定制的。原型模式多用于创建复杂的或者构造耗时的实例,因为这种情况下,复制一个已经存在的实例可使程序运行更高效。
原型模式应用场景

(1)类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等,通过原型拷贝避免这些消耗。
(2)通过new产生的一个对象需要非常繁琐的数据准备或者权限,这时可以使用原型模式。
(3)一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。
Spring框架中的多例就是使用原型。
原型模式UML类图(通用)
原型模式主要用于对象的复制,它的核心是就是类图中的原型类Prototype。Prototype类需要具备以下两个条件:
  (1)实现Cloneable接口。在java语言有一个Cloneable接口,它的作用只有一个,就是在运行时通知虚拟机可以安全地在实现了此接口的类上使用clone方法。在java虚拟机中,只有实现了这个接口的类才可以被拷贝,否则在运行时会抛出CloneNotSupportedException异常。
  (2)重写Object类中的clone方法。Java中,所有类的父类都是Object类,Object类中有一个clone方法,作用是返回对象的一个拷贝,但是其作用域protected类型的,一般的类无法调用,因此Prototype类需要将clone方法的作用域修改为public类型。
原型模式分类
演示实例

/*
 * 书本类型,扮演的是ConcretePrototype角色,而Cloneable扮演Prototype角色
 */
public class Book implements Cloneable {

	private String title;// 标题
	private ArrayList image = new ArrayList();// 图片名列表

	public Book() {
		super();
	}

	/**
	 * 重写拷贝方法
	 */
	@Override
	protected Book clone() {
		try {
			Book book = (Book) super.clone();//
			book.image=(ArrayList)this.image.clone();//深复制
			return book;
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return null;
	}

	public ArrayList getImage() {
		return image;
	}

	public void addImage(String img) {
		this.image.add(img);
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	/**
	 * 打印内容
	 */
	public void showBook() {
		System.out.println("----------------------Start----------------------");

		System.out.println("title:" + title);
		for (String img : image) {
			System.out.println("image name:" + img);
		}

		System.out.println("----------------------End----------------------");
	}
}


客户端代码
public class Client02 {

	public static void main(String[] args) {
		Book book1 = new Book();
		book1.setTitle("书1");
		book1.addImage("图1");
		book1.showBook();
		//以原型方式拷貝一份
		Book book2 = book1.clone();
		book2.showBook();
		book2.setTitle("书2");
		book2.addImage("圖2");
		book2.showBook();
		//再次还原打印书本
		book1.showBook();
		}

}

原型模式分为浅复制和深复制
浅复制 —-只是拷贝了基本类型的数据,而引用类型数据,复制后也是会发生引用,我们把这种拷贝叫做“(浅复制)浅拷贝”,换句话说,浅复制仅仅是指向被复制的内存地址,如果原地址中对象被改变了,那么浅复制出来的对象也会相应改变。
深复制 —-在计算机中开辟了一块新的内存地址用于存放复制的对象。

装饰模式

什么是装饰模式

装饰器模式,也成为包装模式,顾名思义,就是对已经存在的某些类进行装饰,以此来扩展一些功能。其结构图如下:
 Java设计模式 原型模式 策略模式 观察者模式_第1张图片
 Component为统一接口,也是装饰类和被装饰类的基本类型。
ConcreteComponent为具体实现类,也是被装饰类,他本身是个具有一些功能的完整的类。
Decorator是装饰类,实现了Component接口的同时还在内部维护了一个ConcreteComponent的实例,并可以通过构造函数初始化。而Decorator本身,通常采用默认实现,他的存在仅仅是一个声明:我要生产出一些用于装饰的子类了。而其子类才是赋有具体装饰效果的装饰产品类。
ConcreteDecorator是具体的装饰产品类,每一种装饰产品都具有特定的装饰效果。可以通过构造器声明装饰哪种类型的ConcreteComponent,从而对其进行装饰。

装饰模式案例

//房屋基础接口
public interface House {
	 void run();
}
//房屋装饰类
public class HouseDecorate implements House {
   private House house;
   public HouseDecorate(House house){
	  this.house=house;
   }
	@Override
	public void run() {
		house.run();
	}

}
public class HouseDecorateImpl extends HouseDecorate {

	public HouseDecorateImpl(House house) {
		super(house);

	}

	@Override
	public void run() {
		super.run();
		System.out.println("贴上墙纸..");
	}

}
客户端调用
public class ClientTest {

	public static void main(String[] args) {
		HouseImpl houseImpl = new HouseImpl();
		houseImpl.run();
		System.out.println("###新增贴上墙纸..###");
		HouseDecorate houseDecorate = new HouseDecorateImpl(houseImpl);
		houseDecorate.run();
	}

}


装饰与代理区别

装饰器模式关注于在一个对象上动态的添加方法,然而代理模式关注于控制对对象的访问。换句话 说,用代理模式,代理类(proxy class)可以对它的客户隐藏一个对象的具体信息。因此,当使用代理模式的时候,我们常常在一个代理类中创建一个对象的实例。并且,当我们使用装饰器模 式的时候,我们通常的做法是将原始对象作为一个参数传给装饰者的构造器。

装饰模式应用场景
在IO中,具体构件角色是节点流,装饰角色是过滤流。
FilterInputStream和FilterOutputStream是装饰角色,而其他派生自它们的类则是具体装饰角色。
DataoutputStream out=new DataoutputStream(new FileoutputStream());
这就是 装饰者模式,DataoutputStream是装饰者子类,FileoutputStream是实现接口的子类。
这里不会调用到装饰者类–FilteroutputStream,只是作为继承的另一种方案,对客户端来说是透明的,是为了功能的扩张.

策略模式

什么是策略模式

定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
策略模式由三种角色组成
策略模式应用场景
策略模式的用意是针对一组算法或逻辑,将每一个算法或逻辑封装到具有共同接口的独立的类中,从而使得它们之间可以相互替换。策略模式使得算法或逻辑可以在不影响到客户端的情况下发生变化。说到策略模式就不得不提及OCP(Open Closed Principle) 开闭原则,即对扩展开放,对修改关闭。策略模式的出现很好地诠释了开闭原则,有效地减少了分支语句。

策略模式代码
此代码通过模拟不同会员购物车打折力度不同分为三种策略,初级会员,中级会员,高级会员。

//策略模式 定义抽象方法 所有支持公共接口
abstract class Strategy {

	// 算法方法
	abstract void algorithmInterface();

}

class StrategyA extends Strategy {

	@Override
	void algorithmInterface() {
		System.out.println("算法A");

	}

}

class StrategyB extends Strategy {

	@Override
	void algorithmInterface() {
		System.out.println("算法B");

	}

}

class StrategyC extends Strategy {

	@Override
	void algorithmInterface() {
		System.out.println("算法C");

	}

}
// 使用上下文维护算法策略

class Context {

	Strategy strategy;

	public Context(Strategy strategy) {
		this.strategy = strategy;
	}

	public void algorithmInterface() {
		strategy.algorithmInterface();
	}

}

class ClientTestStrategy {
	public static void main(String[] args) {
		Context context;
		context = new Context(new StrategyA());
		context.algorithmInterface();
		context = new Context(new StrategyB());
		context.algorithmInterface();
		context = new Context(new StrategyC());
		context.algorithmInterface();

	}
}

观察者模式

什么是观察者模式

观察者模式(Observer),是一种行为性模型,行为型模式关注的是系统中对象之间的相互交互,解决系统在运行时对象之间的相互通信和协作,进一步明确对象的职责。相比来说,创建型模式关注对象的创建过程,结构型模式关注对象和类的组合关系。
模式的职责

观察者模式主要用于1对N的通知。当一个对象的状态变化时,他需要及时告知一系列对象,令他们做出相应。
实现有两种方式:
推:每次都会把通知以广播的方式发送给所有观察者,所有的观察者只能被动接收。
拉:观察者只要知道有情况即可,至于什么时候获取内容,获取什么内容,都可以自主决定。
模式的实现

//观察者的接口,用来存放观察者共有方法
public interface Observer {
   // 观察者方法
	void update(Subjecct subjecct);
}

//观察对象的父类
public class Subjecct {
	//观察者的存储集合
	private List list = new ArrayList<>();

	// 注册观察者方法
	public void registerObserver(Observer obs) {
		list.add(obs);
	}
    // 删除观察者方法
	public void removeObserver(Observer obs) {
		list.remove(obs);
		this.notifyAllObserver();
	}

	// 通知所有的观察者更新
	public void notifyAllObserver() {
		for (Observer observer : list) {
			observer.update(this);
		}
	}

}
//具体观察者对象的实现
public class RealObserver extends Subjecct {
    //被观察对象的属性
	 private int state;
	 public int getState(){
		 return state;
	 }
	 public void  setState(int state){
		 this.state=state;
		 //主题对象(目标对象)值发生改变
		 this.notifyAllObserver();
	 }
	
}
public class Client {

	public static void main(String[] args) {
		// 目标对象
		RealObserver subject = new RealObserver();
		// 创建多个观察者
		ObserverA obs1 = new ObserverA();
		ObserverA obs2 = new ObserverA();
		ObserverA obs3 = new ObserverA();
		// 注册到观察队列中
		subject.registerObserver(obs1);
		subject.registerObserver(obs2);
		subject.registerObserver(obs3);
		// 改变State状态
		subject.setState(300);
		System.out.println(obs1.getMyState());
		System.out.println(obs2.getMyState());
		System.out.println(obs3.getMyState());
		// 改变State状态
		subject.setState(400);
		System.out.println(obs1.getMyState());
		System.out.println(obs2.getMyState());
		System.out.println(obs3.getMyState());
	}

}

观察者模式应用场景

关联行为场景,需要注意的是,关联行为是可拆分的,而不是“组合”关系。
事件多级触发场景。
跨系统的消息交换场景,如消息队列、事件总线的处理机制。

你可能感兴趣的:(java)