设计模式二

设计模式二,第1张

4:建造者模式

将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。建造者模式是一步一步创建一个复杂对象,它允许用户只通过指定复杂对象的类型和内容就可以构造复杂对象,用户不需要知道内部的具体构建细节。建造者模式属于对象创建型模式。根据中文翻译的不同,建造者模式又可以称为生成器模式。

Builder 抽象建造者
创建建造者的抽象类,定义各个部件的指定抽象接口(建造各部分过程接口),定义getResult()方法用于一次性整体返回建造完成的复杂对象。

ConcreteBuilder 具体建造者
具体实现抽象建造者类定义的各个部件的接口,实现各个部件的装配和构造方法,提供返回复杂对象的方法。

Product 产品类
产品类对象是被建造的复杂对象,包含多个组成部件,具体建造者创建该产品的内部表示并定义它的装配过程。

Director 指挥类
指挥者类负责安排和调度复杂对象的各个建造过程。指挥者类与抽象建造者之间存在关联关系,也就是说指挥者类 内部声明并定义一个 Builder 类型的变量,需要使用具体建造者对象进行初始化,初始化之后Director 再construct () 方法中通过初始化Builder类型变量“指挥”复杂对象的构造过程

案例:建房子

Product 产品类:指定房子有哪些属性

package com.atguigu.builder.improve;

//产品->Product
public class House {
	private String baise;
	private String wall;
	private String roofed;
	public String getBaise() {
		return baise;
	}
	public void setBaise(String baise) {
		this.baise = baise;
	}
	public String getWall() {
		return wall;
	}
	public void setWall(String wall) {
		this.wall = wall;
	}
	public String getRoofed() {
		return roofed;
	}
	public void setRoofed(String roofed) {
		this.roofed = roofed;
	}


	@Override
	public String toString() {
		return "House{" +
				"baise='" + baise + '\'' +
				", wall='" + wall + '\'' +
				", roofed='" + roofed + '\'' +
				'}';
	}
}

Builder 抽象建造者:指定房子建造的通用步骤,不具体实现

package com.atguigu.builder.improve;


// 抽象的建造者
public abstract class HouseBuilder {

	protected House house = new House();
	
	//将建造的流程写好, 抽象的方法
	public abstract void buildBasic();
	public abstract void buildWalls();
	public abstract void roofed();
	
	//建造房子好, 将产品(房子) 返回
	public House buildHouse() {
		return house;
	}
	
}

ConcreteBuilder 具体建造者:指定不同房子具体建造步骤的具体实现,真正实现建造房子

(1)普通房子

package com.atguigu.builder.improve;

public class CommonHouse extends HouseBuilder {

	@Override
	public void buildBasic() {
		// TODO Auto-generated method stub
//		System.out.println(" 普通房子打地基5米 ");
		house.setBaise("普通房子打地基5米");
	}

	@Override
	public void buildWalls() {
		// TODO Auto-generated method stub
//		System.out.println(" 普通房子砌墙10cm ");
		house.setWall("普通房子砌墙10cm");
	}

	@Override
	public void roofed() {
		// TODO Auto-generated method stub
//		System.out.println(" 普通房子屋顶 ");
		house.setRoofed("普通房子屋顶");
	}

}

(2)高层房子

package com.atguigu.builder.improve;

public class HighBuilding extends HouseBuilder {

	@Override
	public void buildBasic() {
		// TODO Auto-generated method stub
//		System.out.println(" 高楼的打地基100米 ");
		house.setBaise("普通房子打地基10米");
	}

	@Override
	public void buildWalls() {
		// TODO Auto-generated method stub
//		System.out.println(" 高楼的砌墙20cm ");
		house.setWall("普通房子砌墙20cm");
	}

	@Override
	public void roofed() {
		// TODO Auto-generated method stub
//		System.out.println(" 高楼的透明屋顶 ");
		house.setRoofed("高楼的透明屋顶");
	}

}

Director 指挥类:规定建房子的流程,即不同步骤先后执行顺序,并返回房子

package com.atguigu.builder.improve;

//指挥者,这里去指定制作流程,返回产品
public class HouseDirector {
	
	HouseBuilder houseBuilder = null;

	//构造器传入 houseBuilder
	public HouseDirector(HouseBuilder houseBuilder) {
		this.houseBuilder = houseBuilder;
	}

	//通过setter 传入 houseBuilder
	public void setHouseBuilder(HouseBuilder houseBuilder) {
		this.houseBuilder = houseBuilder;
	}
	
	//如何处理建造房子的流程,交给指挥者
	public House constructHouse() {
		houseBuilder.buildBasic();
		houseBuilder.buildWalls();
		houseBuilder.roofed();
		return houseBuilder.buildHouse();
	}
	
	
}

具体调用:

package com.atguigu.builder.improve;

public class Client {
	public static void main(String[] args) {
		
		//盖普通房子
		CommonHouse commonHouse = new CommonHouse();
		//准备创建房子的指挥者,说明建造什么样子的房子
		HouseDirector houseDirector = new HouseDirector(commonHouse);
		//指挥者按照不同房子步骤建房子,并返回房子
		House house = houseDirector.constructHouse();
		System.out.println(house.toString());
		
		System.out.println("--------------------------");
		//盖高楼
		HighBuilding highBuilding = new HighBuilding();
		//重置建造者
		houseDirector.setHouseBuilder(highBuilding);
		//完成盖房子,返回产品(高楼)
		House house2 = houseDirector.constructHouse();
		System.out.println(house2.toString());
		
		
		
	}
}
5:适配器模式

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

该模式的主要优点如下。

  • 客户端通过适配器可以透明地调用目标接口。
  • 复用了现存的类,程序员不需要修改原有代码而重用现有的适配者类。
  • 将目标类和适配者类解耦,解决了目标类和适配者类接口不一致的问题。
  • 在很多业务场景中符合开闭原则。

其缺点是:

  • 适配器编写过程需要结合业务场景全面考虑,可能会增加系统的复杂性。
  • 增加代码阅读难度,降低代码可读性,过多使用适配器会使系统代码变得凌乱

适配器模式(Adapter)包含以下主要角色。

  1. 目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。
  2. 适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。
  3. 适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。
 类适配器

        适配器类会继承目标类,并且实现适配者接口

//适配的类
public class Voltage220V {
	//输出220V的电压
	public int output220V() {
		int src = 220;
		System.out.println("电压=" + src + "伏");
		return src;
	}
}


//适配接口
public interface IVoltage5V {
	public int output5V();
}


//适配器类
public class VoltageAdapter extends Voltage220V implements IVoltage5V {

	@Override
	public int output5V() {
		// TODO Auto-generated method stub
		//获取到220V电压
		int srcV = output220V();
		int dstV = srcV / 44 ; //转成 5v
		return dstV;
	}

}


//客户类
public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println(" === 类适配器模式 ====");
		VoltageAdapter adapter = new VoltageAdapter();
		System.out.println(adapter.output5V());

	}

}
 对象适配器

         将目标类传入适配器,直接调用目标类的方法,避免继承


//适配器类
public class VoltageAdapter  implements IVoltage5V {

	private Voltage220V voltage220V; // 关联关系-聚合
	
	
	//通过构造器,传入一个 Voltage220V 实例
	public VoltageAdapter(Voltage220V voltage220v) {
		
		this.voltage220V = voltage220v;
	}



	@Override
	public int output5V() {
		
		int dst = 0;
		if(null != voltage220V) {
			int src = voltage220V.output220V();//获取220V 电压
			System.out.println("使用对象适配器,进行适配~~");
			dst = src / 44;
			System.out.println("适配完成,输出的电压为=" + dst);
		}
		
		return dst;
		
	}

}

//客户类
public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println(" === 对象适配器模式 ====");
		VoltageAdapter adapter = new VoltageAdapter(new Voltage220V());
		System.out.println(adapter.output5V());
	}

}


//其余同上
六:桥接模式

桥接模式即将抽象部分与它的实现部分分离开来,使他们都可以独立变化。

手机案例:

桥接模式主要包含如下几个角色:

  • Abstraction:抽象类。
  • RefinedAbstraction:扩充抽象类。
  • Implementor:实现类接口。
  • ConcreteImplementor:具体实现类 。

实现类接口 Brand

package com.atguigu.bridge;

//接口
public interface Brand {
	void open();
	void close();
	void call();
}

具体实现类  Vivo XiaoMi

public class Vivo implements Brand {

	@Override
	public void open() {
		// TODO Auto-generated method stub
		System.out.println(" Vivo手机开机 ");
	}

	@Override
	public void close() {
		// TODO Auto-generated method stub
		System.out.println(" Vivo手机关机 ");
	}

	@Override
	public void call() {
		// TODO Auto-generated method stub
		System.out.println(" Vivo手机打电话 ");
	}

}



public class XiaoMi implements Brand {

	@Override
	public void open() {
		// TODO Auto-generated method stub
		System.out.println(" 小米手机开机 ");
	}

	@Override
	public void close() {
		// TODO Auto-generated method stub
		System.out.println(" 小米手机关机 ");
	}

	@Override
	public void call() {
		// TODO Auto-generated method stub
		System.out.println(" 小米手机打电话 ");
	}

}

抽象类 Phone 

public abstract class Phone {
	
	//组合品牌
	private Brand brand;

	//构造器
	public Phone(Brand brand) {
		super();
		this.brand = brand;
	}
	
	protected void open() {
		this.brand.open();
	}
	protected void close() {
		brand.close();
	}
	protected void call() {
		brand.call();
	}
	
}

扩充抽象类  FoldedPhone UpRightPhone

//折叠式手机类,继承 抽象类 Phone
public class FoldedPhone extends Phone {

	//构造器
	public FoldedPhone(Brand brand) {
		super(brand);
	}
	
	@Override
	public void open() {
		super.open();
		System.out.println(" 折叠样式手机 ");
	}
	
	@Override
    public void close() {
		super.close();
		System.out.println(" 折叠样式手机 ");
	}
	
	@Override
	public void call() {
		super.call();
		System.out.println(" 折叠样式手机 ");
	}
}


public class UpRightPhone extends Phone {
	
		//构造器
		public UpRightPhone(Brand brand) {
			super(brand);
		}
		
		@Override
		public void open() {
			super.open();
			System.out.println(" 直立样式手机 ");
		}
		
		@Override
        public void close() {
			super.close();
			System.out.println(" 直立样式手机 ");
		}
		
		@Override
		public void call() {
			super.call();
			System.out.println(" 直立样式手机 ");
		}
}

客户端

public class Client {

	public static void main(String[] args) {
		
		//获取折叠式手机 (样式 + 品牌 )
		
		Phone phone1 = new FoldedPhone(new XiaoMi());
		
		phone1.open();
		phone1.call();
		phone1.close();
		
		System.out.println("=======================");
		
		Phone phone2 = new FoldedPhone(new Vivo());
		
		phone2.open();
		phone2.call();
		phone2.close();
		
		System.out.println("==============");
		
		UpRightPhone phone3 = new UpRightPhone(new XiaoMi());
		
		phone3.open();
		phone3.call();
		phone3.close();
		
		System.out.println("==============");
		
		UpRightPhone phone4 = new UpRightPhone(new Vivo());
		
		phone4.open();
		phone4.call();
		phone4.close();
	}

}

说明:桥接模式是将接口组合到抽象类中,抽象类中实现接口,调用接口方法。扩充抽象类则调用抽象类方法。当再次扩充化为手机品牌则只需要实现品牌接口,增加手机样式也只需扩充抽象类。不需要对原有方法进行修改。

1、桥接模式实现了抽象化与实现化的脱耦。他们两个互相独立,不会影响到对方。

2、对于两个独立变化的维度,使用桥接模式再适合不过了。

3、对于"具体的抽象类"所做的改变,是不会影响到客户。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/892238.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-14
下一篇 2022-05-14

发表评论

登录后才能评论

评论列表(0条)

保存