Java之设计模式(结构型模式)

本文介绍了设计模式的概念及其在软件工程中的重要性,详细阐述了设计模式的六大基本原则,并通过实例解析了七大结构型模式,包括适配器模式、装饰模式等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

结构型模式共有7种:

一、适配器模式

1、类(继承)适配器模式

       将原有的类转换成客户端(接口)期望的类,目的是消除由于接口不匹配所造成的类兼容性问题。此模式由3部分组成:

①期望接口

public interface Printer {
    public abstract void printWeak();
    public abstract void printStrong();
}

②适配器

public class BannerAdapter extends Banner implements Printer {
    public BannerAdapter(String str) {
        super(str);
    }
    @Override
    public void printWeak() {
        showWeak();
    }
    @Override
    public void printStrong() {
        showStrong();
    }
}

③被适配者

public class Banner {
    private String str;
    public Banner(String str) {
        this.str = str;
    }
    public void showWeak() {
        System.out.println("(" + this.str + ")");
    }
    public void showStrong() {
        System.out.println("[" + this.str + "]");
    }
}

主入口

public class Main {
    public static void main(String[] args) {
        Printer printer = new BannerAdapter("Hello");
        printer.printWeak();
        printer.printStrong();
    }
}

2、对象(委托)适配器模式

       客户端(抽象类)期望的行为由实际的类对应的对象进行代理,目的是消除由于类不匹配所造成的类兼容性问题。此模式由3部分组成:

①期望抽象类

public abstract class Printer {
    public abstract void printWeak();
    public abstract void printStrong();
}

②适配器

public class BannerAdapter extends Printer {
    private Banner banner;
    public BannerAdapter(String str) {
        this.banner = new Banner(str);
    }
    @Override
    public void printWeak() {
        this.banner.showWeak();
    }
    @Override
    public void printStrong() {
        this.banner.showStrong();
    }
}

③被适配者

public class Banner {
    private String str;
    public Banner(String str) {
        this.str = str;
    }
    public void showWeak() {
        System.out.println("(" + this.str + ")");
    }
    public void showStrong() {
        System.out.println("[" + this.str + "]");
    }
}

主入口

public class Main {
    public static void main(String[] args) {
        Printer printer = new BannerAdapter("Hello");
        printer.printWeak();
        printer.printStrong();
    }
}

结构型模式(7种):适配器模式、装饰模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

        1、适配器模式:。分3种:

        1>类适配器模式:适配器类实现了目标接口,并且继承了被适配的类。适配器类与被适配的类是一种继承关系。此模式由3部分组成:

        ①目标接口:即客户期望成的接口。

public interface Animal{
	public void say();
}

        目标接口的实现:

public class OrdinaryAnimal implements Animal{
	public void say() {
		System.out.println("普通动物的叫声");
	}
}

        ②被适配的类:即通过目标接口也能访问的类

public class People {
	public void speak(){
		System.out.println("人类的语言");
	}
}

        ③适配器类:

public class PeopleAdapter extends People implements Animal {
	public void say(){
		super.speak();
	}
}

        主入口:

public class Test {
	public static void main(String[] args) {
		Animal animal1 = new OrdinaryAnimal();
		animal1.say();
		Animal animal2 = new PeopleAdapter();
		animal2.say();
	}
}

        2>对象适配器模式:适配器类实现了目标接口,并且将被适配的类的作为适配器类的成员变量。适配器类与被适配的类是一种包含关系。此模式由3部分组成:

        ①目标接口:即客户期望成的接口。

public interface Animal{
	public void say();
}

        目标接口的实现:

public class OrdinaryAnimal implements Animal{
	public void say() {
		System.out.println("普通动物的叫声");
	}
}

        ②被适配的类:即通过目标接口也能访问的类

public class People {
	public void speak(){
		System.out.println("人类的语言");
	}
}

        ③适配器类:

public class PeopleAdapter implements Animal {
	private People people;
	public PeopleAdapter(People people){
		this.people=people;
	}
	public void say() {
		people.speak();
	}
}

        主入口:

public class Test {
	public static void main(String[] args) {
		Animal animal1 = new OrdinaryAnimal();
		animal1.say();
		People people = new People();
		Animal animal2 = new PeopleAdapter(people);
		animal2.say();
	}
}

        双向适配器:如果目标接口需要被适配的类适配,而被适配的类也需要目标接口适配,那么就需要将目标接口和被适配的类都作为适配器类的成员变量。

        3>缺省适配器模式(单接口适配器模式):当不需要实现一个接口所提供的所有方法时,可先设计一个抽象类实现该接口,并为接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可以选择性地覆盖父类的某些方法来实现需求,它适用于不想使用接口中的所有方法的情况。

        ①原接口:

public interface Animal{
	public void say();
	public void run();
	public void fly();
}

        ②抽象类:

public abstract class AnimalClass implements Animal {
	public void say(){
	}
	public void run(){
	}
	public void fly(){
	}
}

        ③继承类1:

public class People extends AnimalClass{
	public void say(){
		System.out.println("人类的语言");
	}
	public void run(){
		System.out.println("使用双腿奔跑");
	}
}

        继承类2:

public class Bird extends AnimalClass {
	public void say(){
		System.out.println("鸟的语言");
	}
	public void fly(){
		System.out.println("使用翅膀飞翔");
	}
}

        主入口:

public class Test {
	public static void main(String[] args) {
		Animal people = new People();
		people.say();
		people.run();
		Animal bird = new Bird();
		bird.say();
		bird.fly();
	}
}

        2、装饰模式:动态地给一个对象增加一些额外的功能,就增加对象功能来说,装饰模式比添加继承子类实现更为灵活。此模式由4部分组成:

        ①抽象构件接口:被装饰类和装饰类都会实现此接口,实现统一管理。

public interface Animal {
	public void act();
}

        ②被装饰类:原有的功能,需要在此基础上新增功能。

public class People implements Animal{
	public void act(){
		System.out.println("我可以用双脚走路");
	}
}

        ③抽象装饰类:将构件接口作为本类的成员变量,通过此变量可以调用装饰之前的功能,而实际新增功能是在其子类中实现的。

public class SuperMan implements Animal{
	private Animal animal;
	public SuperMan(Animal animal){
		this.animal=animal;
	}
	public void act() {
		animal.act();
	}
}

        ④具体装饰类:

public class IronMan extends SuperMan {
	public IronMan(Animal animal){
		super(animal);
	}
	public void act() {
		super.act();
		this.addAct();
	}
	public void addAct(){
		System.out.println("我还可以在天空飞");
	}
}

        主入口:

public class Test {
	public static void main(String[] args) {
		Animal animal1 = new People();
		Animal animal2 = new IronMan(animal1);
		animal2.act();
	}
}

        透明装饰模式:要求客户端程序不应该将对象声明为具体构件类型或具体装饰类型,而应该全部声明为抽象构件类型。透明装饰模式可以对一个已装饰过的对象进行多次装饰,得到更为复杂、功能更为强大的对象。

        半透明装饰模式:要求客户端程序必须使用具体的装饰类型(具体装饰类)定义被装饰后的对象,所以不能对一个已装饰过的对象进行多次装饰。

        3、代理模式:使用代理对象来替代实际对象,代理对象和实际对象要实现同一个接口。此模式由3部分组成:

        ①接口:声明了代理对象和实际对象的共同接口。

public interface Human{
	public void act();
}

        ②实际对象:包含实际的业务。

public class RealPeople implements Human{
	public void act(){
		System.out.println("我是真正的幕后老大");
	}
}

        ③代理对象:包含对实际对象的引用,从而在任何时候都可以操作实际对象。

public class proxyPeople implements Human {
	private Human human;
	public proxyPeople(){
		this.human=new RealPeople();
	}
	public void act() {
		human.act();
	}
}

        主入口:

public class Test {
	public static void main(String[] args) {
		Human people = new ProxyPeople();
		people.act();
	}
}

        4、外观模式:对多个对象的访问都是通过同一个对象统一管理统一访问。此模式由2部分组成:

        ①子系统角色1:

public class CPU {
	public void startup(){
		System.out.println("cpu startup!");
	}
	public void shutdown(){
		System.out.println("cpu shutdown!");
	}
}

        子系统角色2:

public class Memory {
	public void startup(){
		System.out.println("memory startup!");
	}
	public void shutdown(){
		System.out.println("memory shutdown!");
	}
}

        子系统角色3:

public class Disk {
	public void startup(){
		System.out.println("disk startup!");
	}
	public void shutdown(){
		System.out.println("disk shutdown!");
	}
}

        ②外观角色:

public class Computer {
	private CPU cpu;
	private Memory memory;
	private Disk disk;
	
	public Computer(){
		cpu = new CPU();
		memory = new Memory();
		disk = new Disk();
	}
	
	public void startup(){
		System.out.println("start the computer!");
		cpu.startup();
		memory.startup();
		disk.startup();
		System.out.println("start computer finished!");
	}
	
	public void shutdown(){
		System.out.println("begin to close the computer!");
		cpu.shutdown();
		memory.shutdown();
		disk.shutdown();
		System.out.println("computer closed!");
	}
}

        主入口:

public class Test {
	public static void main(String[] args) {  
		Computer computer = new Computer();  
		computer.startup();  
		computer.shutdown();  
	}  
}

            5、桥接模式:当某个类同时存在两个独立变化的维度时,需要将这两个维度分离开,使两者可以独立扩展。此模式由4部分组成:

        ①维度1的抽象类:将维度2作为一个成员变量。

public abstract class Pen {
	protected Draw draw;
	Pen(Draw draw){
		this.draw=draw;
	}
	public abstract void draw();
}

        ②维度1的子类1:

public class Pen1 extends Pen {
	Pen1(Draw draw){
		super(draw);
	}
	public void draw() {
		System.out.println("第1种笔正在画");
		this.draw.drawCircle();
	}
}

        维度1的子类2:

public class Pen2 extends Pen {
	Pen2(Draw draw){
		super(draw);
	}
	public void draw() {
		System.out.println("第2种笔正在画");
		this.draw.drawSquare();
	}
}

        维度1的子类3:

public class Pen3 extends Pen {
	Pen3(Draw draw){
		super(draw);
	}
	public void draw() {
		System.out.println("第3种笔正在画");
		this.draw.drawTriangle();
	}
}

        ③维度2的接口:

public interface Draw {
	public void drawCircle();
	public void drawSquare();
	public void drawTriangle();
}

        ④维度2的实现1:

public class Draw1 implements Draw {
	public void drawCircle() {
		System.out.println("画圆的第1种画法");
	}
	public void drawSquare() {
		System.out.println("画矩形的第1种画法");
	}
	public void drawTriangle() {
		System.out.println("画三角形的第1种画法");
	}
}

        维度2的实现2:

public class Draw2 implements Draw {
	public void drawCircle() {
		System.out.println("画圆的第2种画法");
	}
	public void drawSquare() {
		System.out.println("画矩形的第2种画法");
	}
	public void drawTriangle() {
		System.out.println("画三角形的第2种画法");
	}
}

        维度2的实现3:

public class Draw3 implements Draw {
	public void drawCircle() {
		System.out.println("画圆的第3种画法");
	}
	public void drawSquare() {
		System.out.println("画矩形的第3种画法");
	}
	public void drawTriangle() {
		System.out.println("画三角形的第3种画法");
	}
}

        主入口:

public class Test {
	public static void main(String[] args) {
		Draw draw1 = new Draw1();
		Draw draw2 = new Draw2();
		Draw draw3 = new Draw3();
		
		Pen pen1 = new Pen1(draw1);
		Pen pen2 = new Pen2(draw2);
		Pen pen3 = new Pen3(draw3);
		
		pen1.draw();
		pen2.draw();
		pen3.draw();
	}
}

            6、组合模式:也叫部分-整体模式,即组合对象的结构和单个对象的结构是相同的。此时本类的对象作为本类中的一个成员变量,常用于树结构或文件目录中的节点。

TreeNode:

import java.util.Vector;

public class TreeNode {
	private TreeNode parentNode;
	private String nodeName;
	private Vector<TreeNode> childNodes=new Vector<TreeNode>();
	
	TreeNode(String name){
		this.nodeName = name;
	}
	public TreeNode getParentNode() {
		return parentNode;
	}
	public void setParentNode(TreeNode parentNode) {
		this.parentNode = parentNode;
	}
	public String getNodeName() {
		return nodeName;
	}
	public void setNodeName(String nodeName) {
		this.nodeName = nodeName;
	}
	public Vector<TreeNode> getChildNodes() {
		return childNodes;
	}
	public void setChildNodes(Vector<TreeNode> childNodes) {
		this.childNodes = childNodes;
	}
	public void addNode(TreeNode node){
		this.childNodes.add(node);
	}
	public void delNode(int num){
		this.childNodes.remove(num);
	}
	public String getChildNodeNames(TreeNode node){ 
		String nodes = "";
		for(TreeNode tmp:node.childNodes){
			nodes+=tmp.getNodeName()+","+tmp.getChildNodeNames(tmp);
		}
		return nodes;
	}  
}

Tree:

public class Tree {
	static TreeNode root = new TreeNode("root");
	public static void main(String[] args) {
		TreeNode node1 = new TreeNode("node1");
		TreeNode node11 = new TreeNode("node11");
		TreeNode node12 = new TreeNode("node12");
		TreeNode node2 = new TreeNode("node2");
		TreeNode node21 = new TreeNode("node21");
		TreeNode node22 = new TreeNode("node22");
		TreeNode node221 = new TreeNode("node221");
		root.addNode(node1);
		root.addNode(node2);
		node1.addNode(node11);
		node1.addNode(node12);
		node2.addNode(node21);
		node2.addNode(node22);
		node22.addNode(node221);
		System.out.println(root.getChildNodeNames(root));
	}
}

            7、享元模式:主要目的是实现对象的共享,即共享池,当系统中有相应的对象时就不再创建该对象,因此可以减少内存的开销,通常与工厂模式一起使用。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Vector;

public class ConnectionPool{
	private Vector<Connection> pool;
	private int poolSize = 10;
	Connection conn = null;
	
	private String url = "jdbc:mysql://localhost:3306/test";
	private String username = "root";
	private String password = "root";
	private String driverClassName = "com.mysql.jdbc.Driver";

	private ConnectionPool() {
		pool = new Vector<Connection>(poolSize);

		for (int i = 0; i < poolSize; i++) {
			try {
				Class.forName(driverClassName);
				conn = DriverManager.getConnection(url, username, password);
				pool.add(conn);
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	//释放回到连接池 
	public synchronized void release() {
		pool.add(conn);
	}

	//得到连接池中的一个数据库连接 
	public synchronized Connection getConnection() {
		if (pool.size() > 0) {
			Connection conn = pool.get(0);
			pool.remove(conn);
			return conn;
		} else {
			return null;
		}
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值