23种设计模式(创建型、构造型、行为型)

目录

设计模式

创建型模式与对象的创建有关;结构型模式处理类或对象的组合;行为型模式对类或对象怎样交互和怎样分配职责进行描述。

单抽生原,ABCDFFP

一、创建型设计模式

1.1、简单工厂模式(SimpleFactory)

定义:定义一个工厂类,他可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类

在简单工厂模式中用于被创建实例的方法通常为静态(static)方法,因此简单工)厂模式又被成为静态工厂方法(Static Factory Method)

需要什么产品就传入产品对应的参数,就可以获取所需要的产品对象,而无需知道其实现过程

三类角色:
工厂(核心) :负责实现创建所有产品的内部逻辑,工厂类可以被外界直接调用,创建所需对象
抽象产品 :工厂类所创建的所有对象的父类,封装了产品对象的公共方法,所有的具体产品为其子类对象
具体产品:简单工厂模式的创建目标,所有被创建的对象都是某个具体类的实例。它要实现抽象产品中声明的抽象方法

java 复制代码
public class SimpleFactory {
    public static void main(String[] args) {
        Product productA=Factory.createProduct("A");
        productA.info();
        Product productB=Factory.createProduct("B");
        productB.info();
    }
}
//创建类实现方法
class Factory{
    public static Product createProduct(String type){
        Product product=null;
        switch (type){
            case"A":
                product =new ProductA();
                break;
            case"B":
                product=new ProductB();
                break;
            default:
                System.out.println("没有"+type+"产品");
                break;
        }
		return product;
    }
}
//抽象类
abstract class Product{
	//抽象方法info
    public abstract void info();
}
//继承抽象类
class ProductA extends Product{
	//实现抽象方法
    @Override
    public void info() {
        System.out.println("产品信息:A");
    }
}
class ProductB extends Product{

    @Override
    public void info() {
        System.out.println("产品信息:B");
    }
}

1.2、工厂方法(Factory Method)

1)意图

定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。

2)适用性

当一个类不知道它所必须创建的对象的类的时候。

当一个类希望由它的子类来指定它所创建的对象的时候。

当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。

java 复制代码
public class FactoryMethod {
	public static void main(String[] args) {
		//父类 对象名=new 子类()
		Factory fA=new FactoryA();
		//Product productA=new ProductA();
	    Product productA=fA.createProduct();
	    //编译看左边,运行看右边
	    productA.info();
	    
		Factory fB=new FactoryB();
	    Product productB=fB.createProduct();
	    productB.info();
	}
}
//接口Factory
interface Factory{
  public Product createProduct();
}
//FactoryA实现接口
class FactoryA implements Factory{

	@Override
	public Product createProduct() {
		// TODO Auto-generated method stub
		return new ProductA();
	}
	
}
//FactoryB实现接口
class FactoryB implements Factory{

	@Override
	public Product createProduct() {
		// TODO Auto-generated method stub
		return new ProductB();
	}
	
}
//接口Product
interface Product{
  public void info();
}
//ProductA实现接口
class ProductA implements Product{
  @Override
  public void info() {
      System.out.println("产品信息:A");
  }
}
//ProductB实现接口
class ProductB implements Product{

  @Override
  public void info() {
      System.out.println("产品信息:B");
  }
}

1.3、 抽象工厂(Abstarct Factory)

1)意图

提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。

2)适用性

一个系统要独立于它的产品的创建、组合和表示时。

  • 一个系统要由多个产品系列中的一个来配置时。
  • 当要强调一系列相关的产品对象的设计以便进行联合使用时。
  • 当提供一个产品类库,只想显示它们的接口而不是实现时。
java 复制代码
public class AbstractFactory{
	public static void main(String[] args) {
		//父类 对象名=new 子类()
		Factory f1=new Factory1();
		//Product productA=new ProductA();
	    ProductA productA1=f1.createProductA();
	    ProductB productB1=f1.createProductB();
	    //编译看左边,运行看右边
	    productA1.info();
	    productB1.info();
	    
		//父类 对象名=new 子类()
		Factory f2=new Factory2();
	    ProductA productA2=f2.createProductA();
	    ProductB productB2=f2.createProductB();
	    //编译看左边,运行看右边
	    productA2.info();
	    productB2.info();
	    
	}
}
//接口Factory
interface Factory{
  public ProductA createProductA();
  public ProductB createProductB();
}
//Factory1实现接口
class Factory1 implements Factory{

	@Override
	public ProductA createProductA() {
		// TODO Auto-generated method stub
		return new ProductA1();
	}
	@Override
	public ProductB createProductB() {
		// TODO Auto-generated method stub
		return new ProductB1();
	}	
}
//FactoryB实现接口
class Factory2 implements Factory{

	@Override
	public ProductA createProductA() {
		// TODO Auto-generated method stub
		return new ProductA2();
	}

1.4、生成器模式(Builder)

1)意图

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

2)适用性

Builder 模式适用于:当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。当构造过程必须允许被构造的对象有不同的表示时。

  • Builder为创建一个Product 对象的各个部件指定抽象接口。
  • ConcreteBuilder实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,提供一个检索产品的接口。
  • Director 构造一个使用Builder接口的对象。
  • Product表示被构造的复杂对象。
  • ConcreteBuilder创建该产品的内部表示并定义它的装配过程。包含定义组成组件的类,包括将这些组件装配成最终产品的接口。
java 复制代码
import java.util.*;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Director d=new Director();
		//创建生成器对象
		Builder1 b1=new Builder1();
		Builder2 b2=new Builder2();
		//调用参与者的构建方法,其实就是添加信息
		d.Construct(b1);
		d.Construct(b2);
		//将结果存储到产品信息中
		Product p1=b1.getResult();
		Product p2=b2.getResult();
		//显示结果
		p1.show();
		p2.show();
	}

}
//使用Builder接口对象
class Director{
	public void Construct(Builder builder) {
		builder.BuildPart();
	}
}
//各个部件指定接口,抽象生成器
abstract class Builder{
	//生成产品的信息
	public abstract void BuildPart();
	//获取生成的产品
	public abstract Product getResult();
}
//套餐1具体实现
class Builder1 extends Builder{
	Product product=new Product();
	@Override
	public void BuildPart() {
		// TODO Auto-generated method stub
		product.add("A");
		product.add("b");
		product.add("c");
		product.add("d");
	}

	@Override
	public Product getResult() {
		// TODO Auto-generated method stub
		return product;
	}
	
}
//套餐2具体实现
class Builder2 extends Builder{
	Product product=new Product();
	@Override
	public void BuildPart() {
		// TODO Auto-generated method stub;
		product.add("b");
		product.add("c");
	}

	@Override
	public Product getResult() {
		// TODO Auto-generated method stub
		return product;
	}
	
}
//产品信息
class Product{
	List<String> parts=new ArrayList<String>();
	//添加
	public void add(String part) {
		parts.add(part);
	}
	//显示
	public void show() {
		System.out.print("产品的组成");
		for(String s:parts)
			System.out.print(s+" ");
		System.out.print("\n");
	}
}

1.5、 原型模式(Prototype)

1)意图

用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。

2)结构

Prototype声明一个复制自身的接口。

ConcretePrototype实现一个复制自身的操作。

Client 让一个原型复制自身从而创建一个新的对象。

java 复制代码
public class Test_Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Products p1=new Products(2023,11.11);
		System.out.print("id:"+p1.getId()+"   price:"+p1.getPrice()+"\n");
		Products p2=(Products)p1.Clone();
		System.out.print("id:"+p2.getId()+"   price:"+p2.getPrice()+"\n");
	}

}
//原型接口
interface prototype{
	//复制产品的方法
	public Object Clone();
}
//产品
class Products implements prototype{
	private int id;
	private double price;
	
	public Products() {}
	
	public Products(int id,double price) {
		this.id=id;
		this.price=price;
	}
	
	public int getId() {
		return id;
	}

	public double getPrice() {
		return price;
	}

	@Override
	public Object Clone() {
		// TODO Auto-generated method stub
		Products object=new Products();
		//id=当前对象id
		object.id=this.id;
		object.price=this.price;
		
		return object;
	}
}

1.6、 单列模式(Singlcton)

1)意图

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

2)适用性

当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。当这个唯一实例应该是通过子类化可扩展的,并且客户无须更改代码就能使用一个扩展的实例时。

其中:Singleton指定一个Instance操作,允许客户访问它的唯一实例,Instance是一个类操作;可能负责创建它自己的唯一实例。

java 复制代码
public class SingletonPattern {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Singleton s=Singleton.getInstance();
		System.out.print("number= "+s.getNumber()+"\n");
		s.setNumber(2024);
		System.out.print("number= "+s.getNumber()+"\n");
	}

}
class Singleton{
	//测试数据
	private int number=2023;
	public void setNumber(int number) {
		this.number=number;
	}
	public int getNumber() {
		return number;
	}
	
	private static Singleton s=new Singleton();
	//设置私有,保证只有一个实例
	private Singleton() {}
	//设置全局,提供全局访问点
	public static Singleton getInstance() {
		return s;
	}
}

二、结构型设计模式

2.1、适配器模式(Adapter)

1)意图

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

2)适用性

  • Adapter模式适用于:想使用一个已经存在的类,而它的接口不符合要求。
  • 想创建一个可以服用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
  • (仅适用于对象Adapter)想使用一个已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。
  • 对象适配器可以适配它的父类接口。
  • Target 定义Client 使用的与特定领域相关的接口。
  • Client 与符合Target 接口的对象协同。
  • Adaptee定义一个已经存在的接口,这个接口需要适配。
  • Adapter对Adaptee的接口与Target 接口进行适配。
java 复制代码
public class AdapterPattern {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//实例化子类适配器
		Usb u=new Adapter();
		//调用适配器重写的方法
		u.Request();
	}
}
//目标接口Target
class Usb{
	 public void Request() {
		 System.out.println("Usb数据线");
	 }
}
//适配装置
class Adapter extends Usb{
	private Typec t=new Typec();
	@Override
	public void Request() {
		t.SpecificRequest();
	}
}
//需要被适配的请求Adaptee
class Typec{
	public void SpecificRequest() {
		System.out.println("Typec数据线");
	}
}

2.2、桥接模式(Bridge)

1)意图

将抽象部分与其实现部分分离,使它们都可以独立地变化。

  • Abstraction 定义抽象类的接口,维护一个指向Implementor 类型对象的指针。
  • RefinedAbstraction扩充由Abstraction定义的接口。
  • Implementor 定义实现类的接口,该接口不一定要与Abstraction的接口完全一致;事实上这两个接口可以完全不同。一般来说,Implementor接口仅提供基本操作,而Abstraction 定义了基于这些基本操作的较高层次的操作。
  • ConcreteImplementor实现Implementor 接口并定义它的具体实现。
java 复制代码
package ruankao;

public class BridgePattern {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Product_color1 p1=new Product_color1();
		Red red=new Red();
		
		p1.setColor(red);
		p1.setName("产品1");
		p1.Operation();	
	}
}
//抽象产品类
abstract class Product_color{
	//产品名称
	private String name;
	protected Color color;
	
	public String getName() {
		return name;
	}

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

	public Color getColor() {
		return color;
	}

	public void setColor(Color color) {
		this.color = color;
	}
	//抽象方法
	public abstract void Operation();
}
//具体产品A
class Product_color1 extends Product_color{

	@Override
	public void Operation() {
		// TODO Auto-generated method stub
		color.OperationImp(getName());
	}
	
}
//颜色接口
interface Color{
	public void OperationImp(String name);
}
//红色实现接口
class Red implements Color{

	@Override
	public void OperationImp(String name) {
		// TODO Auto-generated method stub 
		System.out.println(name+":红色");
	}	
}
class Blue implements Color{
	@Override
	public void OperationImp(String name) {
		// TODO Auto-generated method stub
		System.out.println(name+":蓝色");
	}	
}

2.3、组合模式(Composite)

1)意图

将对象组合成树型结构以表示=="部分-整体"的层次结构==。Composite使得用户对单个对象和组合对免的体田目有一致性

  • Component为组合中的对象声明接口;在适当情况下实现所有类共有接口的默认行为;声明一个接口用于访问和管理Component的子组件;(可选)在递归结构中定义一个接口,用于访问一个父组件,并在合适的情况下实现它。
  • Leaf在组合中表示叶结点对象,叶结点没有子结点;在组合中定义图元对象的行为。
  • Composite定义有子组件的那些组件的行为;存储子组件;在Component接口中实现与子组件有关的操作。
  • Cient 通过Comnonent接口操纵组合组件的对象。
java 复制代码
package ruankao;

import java.util.*;

public class CompositePattern {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		AbstractFile root=new Folder("root");
		AbstractFile folder=new Folder("folder1");
		AbstractFile file=new File("file1");
		//root打印所有子属性
		root.Add(folder);
		root.Add(file);
		root.printName();
	}
	static void print(AbstractFile file) {
//		file.printName();
		
		//获取抽象文件子集合
		List<AbstractFile> f=file.getChildren();
		//遍历集合中元素
		for(AbstractFile ff:f) {
			ff.printName();
		}
	}
}


//抽象组合
abstract class AbstractFile{
	protected String name;
	public void printName() {
		System.out.println(name);
	}
	//添加文件
	public abstract boolean Add(AbstractFile file);
	//删除文件
	public abstract boolean Remove(AbstractFile file);
	//抽象文件集合
	public abstract List<AbstractFile> getChildren();
}
//目录
class Folder extends AbstractFile{
	private List<AbstractFile> list=new ArrayList<AbstractFile>();
	
	public Folder(String name) {
		this.name=name;
	}

	@Override
	public boolean Add(AbstractFile file) {
		// TODO Auto-generated method stub
		return list.add(file);
	}

	@Override
	public boolean Remove(AbstractFile file) {
		// TODO Auto-generated method stub
		return list.remove(file);
	}

	@Override
	public List<AbstractFile> getChildren() {
		// TODO Auto-generated method stub
		return list;
	}
}
//文件
class File extends AbstractFile{
	public File(String name) {
		this.name=name;
	}

	@Override
	public boolean Add(AbstractFile file) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean Remove(AbstractFile file) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public List<AbstractFile> getChildren() {
		// TODO Auto-generated method stub
		return null;
	}
}

2.4、装饰器模式(Decorator)

1)意图
动态地给一个对象添加一些额外的职责。就增加功能而言,Decorator模式比生成子类更加灵活。

  • Component 定义一个对象接口,可以给这些对象动态地添加职责。
  • ConcreteComponent 定义一个对象,可以给这个对象添加一些职责。
  • Decorator 维持一个指向Component 对象的指针,并定义一个与Component 接口一致的接口。
  • ConcreteDecorator向组件添加职责。
java 复制代码
package ruankao;

public class DecoratorPattern {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Person student=new Student("Daming");
		student.Operaton();
		System.out.println("\n------------------------");
		student=new ConcreteDecoratorA(student);
		student=new ConcreteDecoratorB(student);
		student.Operaton();
		
	}
}
//抽象类人
abstract class Person{
	protected String name;
	public abstract void Operaton();
	
}
//子类学生继承人
class Student extends Person{
	//构造方法
	public Student(String name) {
		this.name=name;
	}
	@Override
	public void Operaton() {
		// TODO Auto-generated method stub
		System.out.print(name+"职责在学习");
	}
}
//装饰器
abstract class Decorator extends Person{
	protected Person person;
}
//具体装饰器A
class ConcreteDecoratorA extends Decorator{
	public ConcreteDecoratorA(Person person) {
		this.person=person;
	}
	@Override
	public void Operaton() {
		// TODO Auto-generated method stub
		person.Operaton();//原本的职责
		System.out.print("  敲代码");
	}
	
}
class ConcreteDecoratorB extends Decorator{
	public ConcreteDecoratorB(Person person) {
		this.person=person;
	}
	@Override
	public void Operaton() {
		// TODO Auto-generated method stub
		person.Operaton();//原本的职责
		System.out.print("  打游戏");
	}
	
}
java 复制代码
Daming职责在学习
------------------------
Daming职责在学习  敲代码  打游戏

2.5、享元模式(Flyweight)

1)意图

运用共享技术有效地支持大量细粒度的对象。

  • Flyweight 模式适用于:
  • 一个应用程序使用了大量的对象。
  • 完全由于使用大量的对象,造成很大的存储开销。对象的大多数状态都可变为外部状态。
  • 如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
  • 应用程序不依赖于对象标识。由于Flyweight对象可以被共享,所以对于概念上明显有别的对象,标识测试将返回真值。
java 复制代码
package ruankao;

public class FlyweightPattern {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		PieceFactory factory=new PieceFactory();
		
		Piece whitePiece1=factory.getPiece(0);
		whitePiece1.draw(2023, 2024);
	}
}
class PieceFactory{
	private Piece[] pieces= {new WhitePiece(),new BlackPiece()};
	
	public Piece getPiece(int key) {
		if(key==0) return pieces[0];
		else return pieces[1];
	}
}
abstract class Piece{
	public String color;
	//位置
	public abstract void draw(int x,int y);
}
class WhitePiece extends Piece{
	public WhitePiece() {
		this.color="white";
	}

	@Override
	public void draw(int x, int y) {
		// TODO Auto-generated method stub
		System.out.println("draw a color"+color+"piece x:"+x+"y:"+y);
	}
}
 
class BlackPiece extends Piece{
	public BlackPiece() {
		this.color="black";
	}

	@Override
	public void draw(int x, int y) {
		// TODO Auto-generated method stub
		System.out.println("draw a color"+color+"piece x:"+x+"y:"+y);
	}
}
java 复制代码
draw a colorwhitepiece x:2023y:2024

三、行为型设计模式

3.1、命令模式(Command)

1)意图

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

  • Command声明执行操作的接口。
  • ConcreteCommand将一个接收者对象绑定于一个动作;调用接收者相应的操作,以实现Execute。
  • Client 创建一个具体命令对象并设定它的接收者。
  • Invoker要求该命令执行这个请求。
  • Receiver知道如何实施与执行一个请求相关的操作。任何类都可能作为一个接收者。
java 复制代码
package ruankao;

public class CommandPattern {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Tv tv=new Tv();//接收者对象电视机
		Command on=new OnCommand(tv);//命令对象  卡机命令
		Command off =new OffCommand(tv);//命令对象  关机命令
		
		Invoker i=new Invoker();//请求者
		i.setCommand(on);//给请求者设置 开机 命令
		i.call();//请求者去请求命令
		
		System.out.println("--------------------");
		
		i.setCommand(off);
		i.call();
				
	}
}
class Invoker{
	private Command command;
	//设置请求者的请求命令
	public void setCommand(Command com) {
		this.command=com;
	}
	public void call() {
		command.Execute();
	}
}
//命令接口
interface Command{
	//执行命令
	public void Execute(); 
}
//开机命令
class OnCommand implements Command{
	private Tv tv;
	
	public OnCommand(Tv tv) {
		this.tv=tv;
	}

	@Override
	public void Execute() {
		// TODO Auto-generated method stub
		tv.OnAction();
	}
}
//关机命令
class OffCommand implements Command{
	private Tv tv;
	
	public OffCommand(Tv tv) {
		this.tv=tv;
	}

	@Override
	public void Execute() {
		// TODO Auto-generated method stub
		tv.OffAcion();
	}
}
//电视
class Tv{
	//开机行为
	public void OnAction() {
		System.out.println("电视机开机");	
	}
	//关机行为
	public void OffAcion() {
		System.out.println("电视机关机");
	}
}
java 复制代码
电视机开机
--------------------
电视机关机

3.2、备忘录模式(Memeto)

1)意图

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

  • Memento(备忘录)存储原发器对象的内部状态,原发器根据需要决定备忘录存储原发器的哪些内部状态;防止原发器以外的其他对象访问备忘录。
  • Originator(原发器)创建一个备忘录,用于记录当前时刻它的内部状态;使用备忘录恢复内部状态。
  • Caretaker(管理者)负责保存好备忘录;不能对备忘录的内容进行操作或检查。
java 复制代码
package ruankao;

import java.util.*;

public class MementoPattern {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Caretaker c=new Caretaker();
		Originator o=new Originator();
		
		o.setState("1024");
		Mementor m=o.createMementor();
		c.addMementor(m);
		
		o.setState("2048");
		Mementor m1=o.createMementor();
		c.addMementor(m1);
		
		System.out.println(o.getState());
		
		c.showMementor();
		
		//恢复到某一状态
		Mementor mm=c.getMementor(1);
		o.setMementor(mm);
		
		System.out.println("根据第一次恢复还原后的状态位"+o.getState());
	}

}
//原发器
class Originator{
	private String state;
	
	public void setState(String state) {
		this.state=state;
	}
	public String getState() {
		return state;
	}
	public Mementor createMementor() {
		return new Mementor(state);
	}
	public void setMementor(Mementor m) {
		state=m.getState();
	}
}
//备忘录
class Mementor{
	private String state;
	
	public Mementor(String state) {
		this.state=state;
	}
	
	public String getState() {
		return state;
	}
}
//管理者
class Caretaker{
	private List<Mementor> mementorlist=new ArrayList<Mementor>();
	public void addMementor(Mementor m) {
		mementorlist.add(m);
	}
	
	public Mementor getMementor(int index) {
		return mementorlist.get(index-1);
	}
	public void showMementor() {
		int count=1;
		for(Mementor m : mementorlist) {
			System.out.println("第几次备份"+count+"备份"+m.getState());
		}
		count++;
	}
}
java 复制代码
2048
第几次备份1备份1024
第几次备份1备份2048
根据第一次恢复还原后的状态位1024

3.3、观察者模式(Observer)

1)意图

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并 被自动更新。

  • Subject(目标)知道它的观察者,可以有任意多个观察者观察同一个目标;提供注册和删除观察者对象的接口。
  • Observer(观察者)为那些在目标发生改变时需获得通知的对象定义一个更新接口。
  • ConcreteSubject(具体目标)将有关状态存入各ConcreteObserver对象;当它的状态发生改变时,向它的各个观察者发出通知。
  • ConcreteObserver(具体观察者)维护一个指向ConcreteSubject对象的引用;存储有关状态,这些状态应与目标的状态保持一致;实现Observer的更新接口,以使自身状态与目标的状态保持一致。
java 复制代码
package ruankao;

import java.util.*;

public class ObserverPattern {
	public static void main(String[] args) {
		//主题
		Subject sbA=new ConcreteSubject();
		//观察者
		Observer ob=new ConcreteObserver("liuwei01",sbA);
		Observer ob1=new ConcreteObserver("liuwei02",sbA);
		Observer ob2=new ConcreteObserver("liuwei03",sbA);
		
		sbA.Notify();
	}
}

//目标接口
interface Subject{
	//添加
	public void Attach(Observer ob);
	//删除
	public void	Detach(Observer ob);
	//状态变化后,通知所有观察者
	public void Notify();
}
class ConcreteSubject implements Subject{
	//观察者集合
	private List<Observer> oblist;
	//构造方法
	public ConcreteSubject() {
		oblist=new ArrayList<Observer>();
	}
	@Override
	public void Attach(Observer ob) {
		// TODO Auto-generated method stub
		oblist.add(ob);
	}

	@Override
	public void Detach(Observer ob) {
		// TODO Auto-generated method stub
		oblist.remove(ob);
	}

	@Override
	public void Notify() {
		// TODO Auto-generated method stub
		for(Observer o:oblist) {
			o.update();
		}
	}  
}

//观察者接口
interface Observer{
	//收到通知更新观察者的状态
	public void update();
}
class ConcreteObserver implements Observer{
	private String name;
	private Subject sb;
	public ConcreteObserver(String name,Subject sb) {
		this.name=name;
		//给观察者指定目标
		this.sb=sb;
		//sb目标添加当前对象,添加到观察者集合中
		sb.Attach(this);
	}
	@Override
	public void update() {
		// TODO Auto-generated method stub
		System.out.println(name+"收到通知");
	}	
}

3.4、状态模式(State)

1)意图

允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

  • 一个对象的行为决定于它的状态,并且它必须在运行时刻根据状态改变它的行为。
  • 一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态常用一个或多个枚举常量表示。通常,有多个操作包含这一相同的条件结构。State模式将每一个条件分支放入一个独立的类中。这使得开发者可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象独立变化。
  • Context(上下文)定义客户感兴趣的接口;维护一个ConcreteState子类的实例,这个实例定义当前状态。
  • State(状态)定义一个接口以封装与Context的一个特定状态相关的行为。
  • ConcreteState(具体状态子类)每个子类实现与Context的一个状态相关的行为。
java 复制代码
public class StateParrent {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Context context=new Context();
		System.out.println(context.getState());
		context.Request();
		context.Request();
		context.Request();
		System.out.println(context.getState());
		
		context.Request(); 
	}
}
class Context{
	//贩卖机
	private int count;
	private State state;
	
	public Context() {
		count=3;
		state=new StateA();
	}
	//设置库存
	public void setCount(int count) {
		this.count=count;
	}
	public int getCount() {
		return count;
	}
	public void setState(State state) {
		this.state=state;
	}
	public State getState() {
		return state;
	}
	public void Request() {
		state.Handle(this);
	}
}
//抽象状态
interface State{
	public void Handle(Context context);
}
//具体状态有货
class StateA implements State{

	@Override
	public void Handle(Context context) {
		// TODO Auto-generated method stub
		int count=context.getCount();
		if(count>=1) {
			//有货-1
			System.out.println("buy successful");
			context.setCount(count-1);
			
			if(context.getCount()==0) {
				//无货
				context.setState(new StateB());
			}
		}else {
			System.out.println("buy error");
		}
	}
}
//无货
class StateB implements State{

	@Override
	public void Handle(Context context) {
		// TODO Auto-generated method stub
		int count=context.getCount();
		if(count==0) {
			System.out.println("buy error ! wait for replenishment");
			//补货
			context.setCount(5);
			System.out.println("replenishment successful");
			//有货
			context.setState(new StateA());
		}
	}
}

3.5、策略模式(Strategy)

1)意图

定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。此模式使得算法可以独立于使用它们的客户而变化。

  • 许多相关的类仅仅是行为有异。"策略"提供了一种用多个行为中的一个行为来配置一个类的方法。
  • 需要使用一个算法的不同变体。例如,定义一些反映不同空间的空间/时间权衡的算法。当这些变体实现为一个算法的类层次时,可以使用策略模式。
  • 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
  • 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,将相关的条件分支移入它们各自的Strategy类中,以代替这些条件语句。
  • Strategy(策略)定义所有支持的算法的公共接口 。Context使用这个接口来调用某ConcreteStrategy定义的算法。
  • ConcreteStrategy(具体策略)以Strategy接口实现某具体算法。
  • Context(上下文)用一个ConcreteStrategy对象来配置;维护一个对Strategy对象的引用;可定义一个接口来让Strategy 访问它的数据。
java 复制代码
package ruankao;

public class StrategyPattern {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Strategy add=new AddStrategy();
		Strategy sub=new SubtractionStrategy();
		Strategy mul=new MultiplicationStrategy();
		
		OperationContext context=new OperationContext(add);
		context.Operation(2023, 2001);
		
		OperationContext context2=new OperationContext(sub);
		context2.Operation(2023, 2001);
		
		OperationContext context3=new OperationContext(mul);
		context3.Operation(2023, 2001);
	}

}
//
class OperationContext{
	private Strategy strategy;
	
	public OperationContext(Strategy strategy) {
		this.strategy=strategy;
	}
	
	public void Operation(int a,int b) {
		strategy.TwoNumberOperation(a, b);
	}
}
//策略
interface Strategy{
	//具体方法
	public void TwoNumberOperation(int a,int b);
}
//具体策略加法
class AddStrategy implements Strategy{

	@Override
	public void TwoNumberOperation(int a, int b) {
		// TODO Auto-generated method stub
		System.out.println(a+b);
	}
	
}

class SubStrategy implements Strategy{

	@Override
	public void TwoNumberOperation(int a, int b) {
		// TODO Auto-generated method stub
		System.out.println(a+b);
	}
	
}

class SubtractionStrategy implements Strategy{

	@Override
	public void TwoNumberOperation(int a, int b) {
		// TODO Auto-generated method stub
		System.out.println(a-b);
	}
	
}

class MultiplicationStrategy implements Strategy{

	@Override
	public void TwoNumberOperation(int a, int b) {
		// TODO Auto-generated method stub
		System.out.println(a*b);
	}	
}

3.6、中介者模式(Mediator)

1)意图

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

3)适用性

Mediator 模式适用于:一组对象以定义良好但是复杂的方式进行通信,产生的相互依赖关系结构混乱且难以理解。一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。想定制一个分布在多个类中的行为,而又不想生成太多的子类。

  1. Mediator(中介者)定义一个接口用于各同事(Colleague)对象通信。
  2. ConcreteMediator(具体中介者)通过协调各同事对象实现协作行为;了解并维护它的各个同事。
  3. Colleague class(同事类)知道它的中介者对象;每一个同事类对象在需要与其他同事通信的时候与它的中介者通信。
java 复制代码
package ruankao;

public class MediatorPattern {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Mediator mediator=new ConcreateMediator();
		
		Colleague1 c1=new Colleague1(mediator);
		Colleague2 c2=new Colleague2(mediator);
		
		mediator.setColleague1(c1);
		mediator.setColleague2(c2);
		
		c1.setMessage("加油");
		c2.setMessage("努力");
	}
}
//同事
abstract class Colleague{
	protected Mediator mediator;
}

class Colleague1 extends Colleague{
	public Colleague1(Mediator mediator) {
		this.mediator=mediator;
	}
	
	public void setMessage(String message) {
		mediator.sendMessge(message, this);
	}
	
	public void notify(String message) {
		System.out.println("同事1收到消息"+message);
	}
}

class Colleague2 extends Colleague{
	public Colleague2(Mediator mediator) {
		this.mediator=mediator;
	}
	
	public void setMessage(String message) {
		mediator.sendMessge(message, this);
	}
	
	public void notify(String message) {
		System.out.println("同事2收到消息"+message);
	}
}
//抽象中介者
abstract class Mediator{
	public abstract void sendMessge(String message,Colleague colleague);
	protected abstract void setColleague1(Colleague1 c1);
	protected abstract void setColleague2(Colleague2 c2);
}
//具体中介者
class ConcreateMediator extends Mediator{
	private Colleague1 colleague1;
	private Colleague2 colleague2;
	public void setColleague1(Colleague1 colleague1) {
		this.colleague1=colleague1;
	}
	public void setColleague2(Colleague2 colleague2) {
		this.colleague2=colleague2;
	}
	@Override
	public void sendMessge(String message, Colleague colleague) {
		// TODO Auto-generated method stub
		if(colleague==colleague1) {
			colleague2.notify(message);
		}else {
			colleague1.notify(message);
		}
	}
}
相关推荐
喵叔哟7 分钟前
重构代码之移动字段
java·数据库·重构
喵叔哟7 分钟前
重构代码之取消临时字段
java·前端·重构
fa_lsyk9 分钟前
maven环境搭建
java·maven
远望清一色16 分钟前
基于MATLAB边缘检测博文
开发语言·算法·matlab
何曾参静谧24 分钟前
「Py」Python基础篇 之 Python都可以做哪些自动化?
开发语言·python·自动化
Prejudices28 分钟前
C++如何调用Python脚本
开发语言·c++·python
Daniel 大东28 分钟前
idea 解决缓存损坏问题
java·缓存·intellij-idea
wind瑞35 分钟前
IntelliJ IDEA插件开发-代码补全插件入门开发
java·ide·intellij-idea
HappyAcmen35 分钟前
IDEA部署AI代写插件
java·人工智能·intellij-idea
马剑威(威哥爱编程)40 分钟前
读写锁分离设计模式详解
java·设计模式·java-ee