如何合理的创建对象?
字面意思就是只能创建一个对象实例时使用。
例如,Windows中只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费,或出现各个窗口显示内容的不一致等错误。
特点:全局就这一个对象时
懒汉式的实现方式如下:
/**
* 懒汉单例模式
*/
public class SingleLazyDemo {
//避免在外部被实例化
private SingleLazyDemo() {
}
private static volatile SingleLazyDemo instance = null;
//实例化
public static synchronized SingleLazyDemo getInstance(){
if(instance == null){
instance = new SingleLazyDemo();
}
return instance;
}
}
测试效果如下:
饿汉式实现方式如下:
public class SingleHungryDemo {
//避免在外部被实例化
private SingleHungryDemo() {
}
private static final SingleHungryDemo instance ;
//一旦加载就创建一个单例
static {
instance = new SingleHungryDemo();
}
//实例化
public static synchronized SingleHungryDemo getInstance(){
return instance;
}
}
饿汉式单例在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以是线程安全的,可以直接用于多线程而不会出现问题。
特点:应用于克隆型对象创建,拷贝原型创建新的对象
原型模式的克隆分为浅克隆和深克隆,Java中的Object类提供了浅克隆的clone()方法,具体原型类只要实现Cloneable接口就可实现对象的浅克隆。
浅克隆的实现方式如下:
import lombok.Data;
@Data
public class PrototypeShallowDemo implements Cloneable{
private String name;
private String describe;
public PrototypeShallowDemo(String name,String describe){
this.name = name;
this.describe = describe;
}
@Override
public String toString(){
return "my name is " + name + ", my info is " + describe;
}
protected Object clone() throws CloneNotSupportedException{
return super.clone();
}
}
测试效果如下:
浅拷贝的特点:
深拷贝可以使用对象序列化的方式实现:
@Data
public class PrototypeDeepDemo implements Cloneable, Serializable {
private String name;
private PrototypeShallowDemo prototypeShallowDemo;
@Override
protected Object clone() throws CloneNotSupportedException {
Object object = super.clone();
PrototypeDeepDemo prototypeDeepDemo = (PrototypeDeepDemo) object;
prototypeDeepDemo.prototypeShallowDemo = (PrototypeShallowDemo) prototypeShallowDemo.clone();
return object;
}
}
特点:创建于使用分离,将创建的对象作为“产品”,把创建产品的对象称为“工厂”。
满足“开闭原则”的前提下,客户随意增删或改变对软件相关对象的使用。
首先实现要生产的产品:
//定一个产品类
public interface Product {
public String Show();
}
//具体产品1
public class ProductCoffee implements Product{
@Override
public String Show() {
return "this is coffee";
}
}
//具体产品2
public class ProductPhone implements Product{
@Override
public String Show() {
return "this is phone";
}
}
然后实现生产工厂:
//定义一个抽象工厂,使用接口interface或者抽象abstract
public interface AbstractFactory {
public Product CreateProduct();
}
//具体的生产工厂1
public class FactoryCoffee implements AbstractFactory{
@Override
public Product CreateProduct() {
return new ProductCoffee();
}
}
//具体的生产工厂2
public class FactoryPhone implements AbstractFactory{
@Override
public Product CreateProduct() {
return new ProductPhone();
}
}
测试实例,调用不同的工厂生产产品:
@GetMapping("/demo4")
public String demo4() {
FactoryCoffee factoryCoffee = new FactoryCoffee();
Product product = factoryCoffee.CreateProduct();
FactoryPhone factoryPhone = new FactoryPhone();
return product.Show() + "______" + factoryPhone.CreateProduct().Show();
}
抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。
使用抽象工厂模式一般要满足以下条件。
① 系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。
② 系统一次只可能消费其中某一族产品,即同族的产品一起使用。
在抽象工厂模式包含如下几个角色:
1)创建抽象产品和具体产品
//抽象产品1
public abstract class Animal {
public abstract void getName();
public abstract void addFood();
public abstract void getColor();
}
//具体动物1
public class Horse extends Animal{
@Override
public void getName() {
System.out.println("this name is horse");
}
@Override
public void addFood() {
System.out.println("添加食物");
}
@Override
public void getColor() {
System.out.println("白色");
}
}
//具体动物2
public class Cattle extends Animal{
@Override
public void getName() {
System.out.println("this name is cattle");
}
@Override
public void addFood() {
System.out.println("添加食物");
}
@Override
public void getColor() {
System.out.println("黑色");
}
}
//抽象产品2
public abstract class Plant {
public abstract void getName();
public abstract void addWater();
}
//具体植物1
public class Fruit extends Plant{
@Override
public void getName() {
System.out.println("这是水果");
}
@Override
public void addWater() {
System.out.println("浇水");
}
}
//具体植物2
public class Vegetable extends Plant{
@Override
public void getName() {
System.out.println("这是蔬菜");
}
@Override
public void addWater() {
System.out.println("浇水");
}
}
2)抽象工厂
public interface Farm {
public Plant createPlant();
public Animal createAnimal();
}
3)具体工厂
//具体工厂1
public class HongXingFarm implements Farm{
@Override
public Plant createPlant() {
System.out.println("蔬菜产生");
return new Vegetable();
}
@Override
public Animal createAnimal() {
System.out.println("牛产生");
return new Cattle();
}
}
//具体工厂2
public class MingLeFarm implements Farm{
@Override
public Plant createPlant() {
System.out.println("水果产生");
return new Fruit();
}
@Override
public Animal createAnimal() {
System.out.println("马产生");
return new Horse();
}
}
4)测试
@GetMapping("/demo5")
public void demo5(){
Farm farm ;
Animal animal;
Plant plant;
farm = new HongXingFarm();
animal = farm.createAnimal();
plant = farm.createPlant();
animal.getName();
animal.addFood();
plant.getName();
plant.addWater();
}
背景:在软件开发过程中有时需要创建一个复杂的对象,这个复杂对象通常由多个子部件按一定的步骤组合而成。例如,计算机是由CPU、主板、内存、硬盘、显卡、机箱、显示器、键盘、鼠标等部件组装而成的。
它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
建造者模式的主要角色如下:
1)设计产品构成
public class Product {
private String partA;
private String partB;
private String partC;
public void setPartA(String partA) {
this.partA = partA;
}
public void setPartB(String partB) {
this.partB = partB;
}
public void setPartC(String partC) {
this.partC = partC;
}
public void show()
{
System.out.println(partA + partB + partC);
}
}
2)建造者,负责进行产品的组装
public abstract class Builder {
//创建产品对象
protected Product product=new Product();
public abstract void buildPartA();
public abstract void buildPartB();
public abstract void buildPartC();
//返回产品对象
public Product getResult() {
return product;
}
}
3)具体构造者,实现具体的构建细节
public class HongXIngBuilder extends Builder{
@Override
public void buildPartA() {
product.setPartA("建造PartA");
}
@Override
public void buildPartB() {
product.setPartB("建造PartB");
}
@Override
public void buildPartC() {
product.setPartC("建造PartC");
}
}
4)指挥者,选择具体构建者进行构建
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder=builder;
}
//产品构建与组装方法
public Product construct() {
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
return builder.getResult();
}
}
5)使用
@GetMapping("/demo6")
public void demo6(){
//选择HongXIngBuilder
Builder builder1 = new HongXIngBuilder();
Director director1 = new Director(builder1);
Product product1 = director1.construct();
product1.show();
}
结构型模式字面意思就是设计程序结构的。
代理就类似于中介,某些情况下不能或者不想直接访问另一个对象,这时需要找一个中介帮忙完成某项任务,这个中介就是代理对象。
代理模式的主要角色如下:
1)抽象主题
public interface Subject {
void Request();
void GetInfo();
}
2)真实主题
public class RealSubject implements Subject{
@Override
public void Request() {
System.out.println("【*】开始访问 ");
}
@Override
public void GetInfo() {
System.out.println("【info】信息展示 " + new Date());
}
}
3)代理
public class Proxy implements Subject{
private RealSubject realSubject;
@Override
public void Request() {
if(realSubject == null){
realSubject = new RealSubject();
}
preRequest();
realSubject.Request();
postRequest();
}
@Override
public void GetInfo() {
if(realSubject == null){
realSubject = new RealSubject();
}
realSubject.GetInfo();
}
4)使用
@GetMapping("/demo7")
public void demo7(){
Proxy proxy = new Proxy();
proxy.GetInfo();
proxy.Request();
}
开发中两个对象因接口不兼容而不能在一起工作的实例,这时需要第三者进行适配。适配器模式就是将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。
适配器模式包含以下主要角色:
1)目标接口
public interface Target {
void Request();
}
2)适配目标类
public class Adapter {
public void specificRequest(){
System.out.println("适配具体请求");
}
}
3)适配器
public class TargetAdapter extends Adapter implements Target {
@Override
public void Request() {
specificRequest();
}
}
4)使用
@GetMapping("/demo8")
public void demo8(){
Target target = new TargetAdapter();
target.Request();
}
将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。
桥接(Bridge)模式包含以下主要角色:
比如4种类型画笔,3种颜色,实现一个画板:
实现方式1: 四种画笔,每种画笔创建三种颜色,共4 *3 = 12 个类
实现方式2:如下,四个形状具体实现类,三个颜色具体实现类,然后定义双继承,也是12个类
实现方式3:如下,用个“桥”去拼接形状和颜色,只有一座“桥”所以类的数量就看上面的4+3=7
//实现化角色
public interface Impl {
public void ImplInfo();
}
//具体实现化角色
public class TypeOneImpl implements Impl{
@Override
public void ImplInfo() {
System.out.println("具体实现1");
}
}
//抽象化角色
public abstract class Abstr {
protected Impl impl;
protected Abstr(Impl impl){
this.impl = impl;
}
public abstract void Operation();
}
//扩展抽象化角色
public class AbstrOne extends Abstr{
public AbstrOne(Impl impl) {
super(impl);
}
@Override
public void Operation() {
System.out.println("扩展抽象化访问");
impl.ImplInfo();
}
}
//使用
@GetMapping("/demo9")
public void demo9(){
Impl impl = new TypeOneImpl();
Abstr abstr = new AbstrOne(impl);
abstr.Operation();
}
在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式。
装饰模式主要包含以下角色:
1)抽象构件角色
public interface Shape {
void draw();
}
2)具体构件角色,未被修饰的原本的内容
public class Rectangle implements Shape{
@Override
public void draw() {
System.out.println("Shape: Rectangle");
}
}
public class Circle implements Shape{
@Override
public void draw() {
System.out.println("Shape: Circle");
}
}
3)抽象修饰角色
public abstract class ShapeDecorator implements Shape{
protected Shape shape;
public ShapeDecorator(Shape shape){
this.shape = shape;
}
public void draw(){
shape.draw();
}
}
4)具体修饰角色,添加修饰类型——颜色修饰
public class RedShapeDecorator extends ShapeDecorator{
public RedShapeDecorator(Shape shape) {
super(shape);
}
@Override
public void draw(){
shape.draw();
setRedBorder(shape);
}
private void setRedBorder(Shape shape){
System.out.println("Border Color: Red");
}
}
5)使用
@GetMapping("/demo10")
public void demo10(){
Shape shapeCircle = new Circle();
ShapeDecorator redCircle = new RedShapeDecorator(new Circle());
ShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());
shapeCircle.draw();
System.out.println("-----");
redCircle.draw();
redRectangle.draw();
}
当一个系统的功能越来越强,子系统会越来越多,客户对系统的访问也变得越来越复杂。这时如果系统内部发生改变,客户端也要跟着改变,这违背了“开闭原则”,也违背了“迪米特法则”,所以有必要为多个子系统提供一个统一的接口,从而降低系统的耦合度。
外观模式包含以下主要角色:
1)外观角色
public interface Shape {
void draw();
}
2)子系统
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Rectangle::draw()");
}
}
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Square::draw()");
}
}
3)客户角色
public class ShapeMaker {
private Shape circle;
private Shape rectangle;
public ShapeMaker() {
circle = new Circle();
rectangle = new Rectangle();
square = new Square();
}
public void drawCircle(){
circle.draw();
}
public void drawRectangle(){
rectangle.draw();
}
}
4)使用
ShapeMaker shapeMaker = new ShapeMaker();
shapeMaker.drawCircle();
shapeMaker.drawRectangle();
在面向对象程序设计过程中,有时会面临要创建大量相同或相似对象实例的问题。
运用共享技术来有效地支持大量细粒度对象的复用。
享元模式的主要角色有如下:
1)非享元
public class UnSharedFlyweight {
private String info;
public UnSharedFlyweight(String info){
this.info = info;
}
public String getInfo(){
return info;
}
public void setInfo(String info){
this.info = info;
}
}
2)抽象享元
public interface AbstractFlyweight {
void operation(UnSharedFlyweight unSharedFlyweight);
}
3)具体享元
public class ConcreteFlyweight implements AbstractFlyweight{
private String key;
public ConcreteFlyweight(String key){
this.key = key;
System.out.println("具体享元" + key + "被创建!");
}
@Override
public void operation(UnSharedFlyweight unSharedFlyweight) {
System.out.print("具体享元" + key + "被调用, ");
System.out.println("非享元信息是 " + unSharedFlyweight.getInfo());
}
}
4)享元工厂
public class FlyweightFactory {
private HashMap flyweights = new HashMap();
public AbstractFlyweight getFlyweight(String key){
AbstractFlyweight flyweight = flyweights.get(key);
if(flyweight != null){
System.out.println("具体享元" + key + "已经存在,获取成功!");
}else{
flyweight = new ConcreteFlyweight(key);
flyweights.put(key,flyweight);
}
return flyweight;
}
}
5)使用
@GetMapping("/demo11")
public void demo11(){
FlyweightFactory factory = new FlyweightFactory();
AbstractFlyweight flyweight1 = factory.getFlyweight("a");
AbstractFlyweight flyweight2 = factory.getFlyweight("a");
AbstractFlyweight flyweight3 = factory.getFlyweight("b");
AbstractFlyweight flyweight4 = factory.getFlyweight("b");
AbstractFlyweight flyweight5 = factory.getFlyweight("b");
flyweight1.operation(new UnSharedFlyweight("第一次调用a"));
flyweight2.operation(new UnSharedFlyweight("第二次调用a"));
flyweight3.operation(new UnSharedFlyweight("第一次调用b"));
flyweight4.operation(new UnSharedFlyweight("第二次调用b"));
flyweight5.operation(new UnSharedFlyweight("第三次调用b"));
}
实例应用:棋子(ChessPieces)类是抽象享元角色,它包含了一个落子的DownPieces(Graphics g,Point pt)方法;白子(WhitePieces)和黑子(BlackPieces)类是具体享元角色,它实现了落子方法;Point是非享元角色,它指定了落子的位置;WeiqiFactory是享元工厂角色,它通过ArrayList来管理棋子,并且提供了获取白子或者黑子的getChessPieces(String type)方法。
有时又叫作部分-整体模式,它是一种将对象组合成树状的层次结构的模式,用来表示“部分-整体”的关系,使用户对单个对象和组合对象具有一致的访问性。
透明组合模式
//抽象构件
interface Component {
public void add(Component c);
public void remove(Component c);
public Component getChild(int i);
public void operation();
}
//树叶构件
class Leaf implements Component {
private String name;
public Leaf(String name) {
this.name = name;
}
public void add(Component c) {
}
public void remove(Component c) {
}
public Component getChild(int i) {
return null;
}
public void operation() {
System.out.println("树叶" + name + ":被访问!");
}
}
//树枝构件
class Composite implements Component {
private ArrayList children = new ArrayList();
public void add(Component c) {
children.add(c);
}
public void remove(Component c) {
children.remove(c);
}
public Component getChild(int i) {
return children.get(i);
}
public void operation() {
for (Object obj : children) {
((Component) obj).operation();
}
}
}
//使用
Component c0 = new Composite();
Component c1 = new Composite();
Component leaf1 = new Leaf("1");
Component leaf2 = new Leaf("2");
Component leaf3 = new Leaf("3");
c0.add(leaf1);
c0.add(c1);
c1.add(leaf2);
c1.add(leaf3);
c0.operation();
场景:设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的实现与具体的环境相关。又例如例如,简历模板、论文模板、Word中模板文件等。
模版方法模式特点如下:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。
模板方法模式包含以下主要角色:
(1)抽象类(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。这些方法的定义如下
① 模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。
② 基本方法:是整个算法中的一个步骤,包含以下几种类型。
(2)具体子类(Concrete Class):实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的一个组成步骤。
//抽象类
public abstract class StencilAbstract {
public void TemplateMethod() { //模版方法
SpecificMethod();
abstractMethod1();
abstractMethod2();
}
public void SpecificMethod(){ //具体方法
System.out.println("抽象类中的具体方法被调用");
}
public abstract void abstractMethod1();
public abstract void abstractMethod2();
}
//具体子类
public class ConcreteStencil extends StencilAbstract {
@Override
public void abstractMethod1() {
System.out.println("抽象方法1的实现调用");
}
@Override
public void abstractMethod2() {
System.out.println("抽象方法2的实现调用");
}
}
//调用
@GetMapping("/demo12")
public void demo12(){
StencilAbstract sa = new ConcreteStencil();
sa.TemplateMethod();
}
当实现某一个功能存在多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能。
策略模式:定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。
策略模式的主要角色如下:
1)抽象策略类
public interface AbstractStrategy {
public void strategyMethod();
}
2)具体策略类
//具体实现方法2
public class ConcreteStrategyA implements AbstractStrategy{
@Override
public void strategyMethod() {
System.out.println("具体策略A的策略方法被访问!");
}
}
//具体实现方法1
public class ConcreteStrategyB implements AbstractStrategy{
@Override
public void strategyMethod() {
System.out.println("具体策略B的策略方法被访问!");
}
}
3)环境类
public class EnvironmentContext {
private AbstractStrategy strategy;
public AbstractStrategy getStrategy(){
return strategy;
}
public void setStrategy(AbstractStrategy getStrategy){
this.strategy = strategy;
}
public void strategyMethod(){
strategy.strategyMethod();
}
}
4)调用
@GetMapping("/demo13")
public void demo13(){
EnvironmentContext context = new EnvironmentContext();
AbstractStrategy strategy = new ConcreteStrategyA();
context.setStrategy(strategy);
context.strategyMethod();
System.out.println("_______________");
strategy = new ConcreteStrategyB();
context.setStrategy(strategy);
context.strategyMethod();
}
背景:在软件开发系统中,常常出现“方法的请求者”与“方法的实现者”之间存在紧密的耦合关系。
命令模式:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。
命令模式包含以下主要角色:
1)抽象命令类
//抽象命令
public interface Command {
public abstract void execute();
}
2)具体命令类
public class ConcreteCommand implements Command{
private Receiver receiver;
public ConcreteCommand(){
receiver = new Receiver();
}
@Override
public void execute() {
receiver.action();
}
}
3)调用者,发起请求的地方
public class Invoker {
private Command command;
public Invoker (Command command){
this.command = command;
}
public void setCommand(Command command){
this.command = command;
}
public void call(){
System.out.println("调用者治性命令!");
command.execute();
}
}
4)接收者,真正实现业务的地方
public class Receiver {
public void action(){
System.out.println("接受者的action()方法被调用");
}
}
5)调用实现
@GetMapping("/demo14")
public void demo14(){
Command cmd = new ConcreteCommand();
Invoker invoker = new Invoker(cmd);
invoker.call();
}
背景:一个请求有多个对象可以处理,但每个对象的处理条件或权限不同。例如Struts2的拦截器、JSP和Servlet的Filter。
职责链模式:为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。
职责链模式主要包含以下角色:
1)抽象处理者
public abstract class RCAbstractHandler {
private RCAbstractHandler next;
public void setNext(RCAbstractHandler next){
this.next = next;
}
public RCAbstractHandler getNext(){
return next;
}
//处理请求的方法
public abstract void handleRequest(String request);
}
2)具体处理者
//具体处理者1
public class ConcreteHandle1 extends RCAbstractHandler{
@Override
public void handleRequest(String request) {
if(request.contains("a")){
System.out.println("ConcreteHandle1 开始处理");
}else {
if(getNext() != null){
getNext().handleRequest(request);
}else{
System.out.println("无处理");
}
}
}
}
//具体处理者2
public class ConcreteHandle2 extends RCAbstractHandler{
@Override
public void handleRequest(String request) {
if(request.contains("b")){
System.out.println("ConcreteHandle2 开始处理");
}else {
if(getNext() != null){
getNext().handleRequest(request);
}else{
System.out.println("无处理");
}
}
}
}
3)调用
@GetMapping("/demo15")
public void demo15(@RequestParam("content") String content){
RCAbstractHandler handler1 = new ConcreteHandle1();
RCAbstractHandler handler2 = new ConcreteHandle2();
handler1.setNext(handler2);
handler1.handleRequest(content);
}
背景:应用程序中的有些对象可能会根据不同的情况做出不同的行为,我们把这种对象称为有状态的对象。
状态模式:对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。
状态模式包含以下主要角色:
1)环境角色
public class StateContext {
private State state;
public StateContext(){
this.state = new ConcreteStateA();
}
public void setState(State state){
this.state = state;
}
public State getState(){
return state;
}
public void Handle(State state){
state.Handle(this,state);
}
}
2)抽象状态
public abstract class State {
public abstract void Handle(StateContext context,State state);
}
3)具体状态
//具体算法A
public class ConcreteStateA extends State{
@Override
public void Handle(StateContext context,State state) {
System.out.println("this is A");
context.setState(state);
}
}
//具体算法B
public class ConcreteStateB extends State{
@Override
public void Handle(StateContext context,State state) {
System.out.println("this is B");
context.setState(state);
}
}
4)调用
@GetMapping("/demo16")
public void demo16(){
StateContext context = new StateContext();
context.Handle(new ConcreteStateA());
context.Handle(new ConcreteStateA());
context.Handle(new ConcreteStateB());
}
背景:在现实世界中,许多对象并不是独立存在的,其中一个对象的行为发生改变可能会导致一个或者多个其他对象的行为也发生改变
观察者(订阅者)模式:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
观察者模式的主要角色如下:
1)抽象主题角色
public abstract class ObserverSubject {
protected List observers=new ArrayList();
//增加观察者方法
public void add(Observer observer)
{
observers.add(observer);
}
//删除观察者方法
public void remove(Observer observer)
{
observers.remove(observer);
}
public abstract void notifyObserver(String info); //通知观察者方法
}
2)具体主题
public class ObConcreteSubject extends ObserverSubject {
@Override
public void notifyObserver(String info) {
System.out.println("具体目标发生改变...");
System.out.println("--------------");
for(Object obs:observers)
{
((Observer)obs).response(info);
}
}
}
3)抽象观察者
public interface Observer {
void response(String info);
}
4)具体观察者角色
//具体观察者1
public class ObConcreteObserver1 implements Observer{
@Override
public void response(String info) {
System.out.println("具体观察者1作出反应:" + info);
}
}
//具体观察者2
public class ObConcreteObserver1 implements Observer{
@Override
public void response(String info) {
System.out.println("具体观察者1作出反应:" + info);
}
}
5)调用
@GetMapping("/demo17")
public void demo17(){
ObserverSubject subject = new ObConcreteSubject();
Observer observer1 = new ObConcreteObserver1();
Observer observer2 = new ObConcreteObserver2();
subject.add(observer1);
subject.add(observer2);
subject.notifyObserver("降价了!");
}
背景:在现实生活中,常常会出现好多对象之间存在复杂的交互关系,这种交互关系常常是“网状结构”,它要求每个对象都必须知道它需要交互的对象。
中介模式(调停模式):定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。
中介者模式包含以下主要角色:
1)中介者
//抽象中介者
public abstract class AbstractMediator {
public abstract void register(AbstractCollege college);
public abstract void replay(AbstractCollege cl);
}
//具体中介者
public class ConcreteMediator extends AbstractMediator{
private List colleges = new ArrayList<>();
@Override
public void register(AbstractCollege college) {
if(!colleges.contains(college)){
colleges.add(college);
college.setMediator(this);
}
}
@Override
public void replay(AbstractCollege cl) {
for(AbstractCollege college : colleges){
if(!college.equals(cl)){
college.receive();
}
}
}
}
2)同事类
//抽象
public abstract class AbstractCollege {
protected AbstractMediator mediator;
public void setMediator(AbstractMediator mediator){
this.mediator = mediator;
}
public abstract void receive();
public abstract void send();
}
//具体1
public class ConcreteCollege1 extends AbstractCollege{
@Override
public void receive() {
System.out.println("college1 收到请求 ");
}
@Override
public void send() {
System.out.println("college1 发出请求 ");
mediator.replay(this);//转发
}
}
//具体2
public class ConcreteCollege2 extends AbstractCollege {
@Override
public void receive() {
System.out.println("college2 收到请求 ");
}
@Override
public void send() {
System.out.println("college2 发出请求 ");
mediator.replay(this);
}
}
3)调用
@GetMapping("/demo18")
public void demo18(){
AbstractMediator mediator = new ConcreteMediator();
AbstractCollege c1,c2;
c1 = new ConcreteCollege1();
c2 = new ConcreteCollege2();
mediator.register(c1);
mediator.register(c2);
c1.send();
c2.send();
}
不同对象之间的信息沟通
提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。
迭代器模式主要包含以下角色:
1)抽象聚合
public interface IteratorAggregate {
public void add(Object obj);
public void remove(Object obj);
public Iterator getIterator();
}
2)具体聚合
public class ConcreteAggregate implements IteratorAggregate{
private List
3)抽象迭代器
public interface Iterator {
Object first();
Object next();
boolean hashNext();
}
4)具体迭代器
public class ConcreteIterator implements Iterator{
private List
5)调用
@GetMapping("/demo19")
public void demo19(){
IteratorAggregate ag = new ConcreteAggregate();
ag.add("中山大学");
ag.add("华南理工");
ag.add("清华大学");
ag.add("北大大学");
Iterator it = ag.getIterator();
while(it.hashNext()){
Object ob = it.next();
System.out.println(ob.toString() + "\n");
}
Object ob = it.first();
System.out.println("\nFirst" + ob.toString());
}
背景:有些集合对象中存在多种不同的元素,且每种元素也存在多种不同的访问者和处理方式。
访问者模式定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。
访问者模式包含以下主要角色:
1)抽象访问者
public interface AbstractVisitor {
void visit(ConcreteElementA element);
void visit(ConcreteElementB element);
}
2)具体访问者
//具体访问者A
public class ConcreteVisitorA implements AbstractVisitor{
@Override
public void visit(ConcreteElementA element) {
System.out.println("具体A访问者访问:" + element.Operation());
}
@Override
public void visit(ConcreteElementB element) {
System.out.println("具体A访问者访问:" + element.Operation());
}
}
//具体访问者B
public class ConcreteVisitorB implements AbstractVisitor{
@Override
public void visit(ConcreteElementA element) {
System.out.println("具体B访问者访问:" + element.Operation());
}
@Override
public void visit(ConcreteElementB element) {
System.out.println("具体B访问者访问:" + element.Operation());
}
}
3)抽象元素
public interface Element {
void accept(AbstractVisitor visitor);
}
4)具体元素
//具体元素A
public class ConcreteElementA implements Element{
@Override
public void accept(AbstractVisitor visitor) {
visitor.visit(this);
}
public String Operation(){
return "具体元素A的操作!";
}
}
//具体元素B
public class ConcreteElementB implements Element{
@Override
public void accept(AbstractVisitor visitor) {
visitor.visit(this);
}
public String Operation(){
return "具体元素B的操作!";
}
}
5)对象结构元素
public class ObjectStructure {
private List list = new ArrayList();
public void accept(AbstractVisitor visitor){
Iterator element = list.iterator();
while(element.hasNext()){
element.next().accept(visitor);
}
}
public void add(Element element){
list.add(element);
}
public void remove(Element element){
list.remove(element);
}
}
6)调用
@GetMapping("/demo20")
public void demo20(){
ObjectStructure obs = new ObjectStructure();
obs.add(new ConcreteElementA());
obs.add(new ConcreteElementB());
AbstractVisitor visitorA = new ConcreteVisitorA();
obs.accept(visitorA);
AbstractVisitor visitorB = new ConcreteVisitorB();
obs.accept(visitorB);
}
备忘录模式(快照模式)能记录一个对象的内部状态,当用户后悔时能撤销当前操作,使数据恢复到它原先的状态。
备忘录模式的主要角色如下:
1)备忘录
public class Memento {
private String state;
public Memento (String state){
this.state = state;
}
public void setState(String state){
this.state = state;
}
public String getState(){
return state;
}
}
2)发起人
public class Originator {
private String state;
public void setState(String state){
this.state = state;
}
public String getState(){
return state;
}
public Memento createMemento(){
return new Memento(state);
}
public void restoreMemento(Memento m){
this.setState(m.getState());
}
}
3)管理者
public class Caretaker {
private Memento memento;
public void setMemento(Memento m){
this.memento = m;
}
public Memento getMemento(){
return memento;
}
}
4)调用
@GetMapping("/demo21")
public void demo21(){
Originator or = new Originator();
Caretaker cr = new Caretaker();
or.setState("S0");
System.out.println("初始状态:" + or.getState());
cr.setMemento(or.createMemento()); //保存状态
or.setState("S1");
System.out.println("新的状态:" + or.getState());
or.restoreMemento(cr.getMemento()); //恢复状态
System.out.println("恢复状态:" + or.getState());
}