《java开发实战经典》李兴华——C6. 面向对象(高级篇)——Part2 设计模式

本文探讨了面向对象设计模式中的四个关键部分:工厂设计模式通过接口和子类之间的过渡解决代码耦合问题;代理设计模式利用代理主题处理额外业务,保护真实主题;适配器设计模式允许类以不同的方式实现接口;观察者设计模式实现了一对多的依赖关系,当对象状态改变时,所有依赖者都会收到通知并自动更新。

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

一、工厂设计

1.首先观察一般程序中的问题:

interface Fruit{
	public void eat();
}

class Apple implements Fruit{
	@Override
	public void eat() {
		System.out.println("吃苹果。");
	}
}

class Orange implements Fruit{
	@Override
	public void eat() {
		System.out.println("吃橘子。");
	}
}

public class Test {
	public static void main(String args[]) {
		Fruit f1 = new Apple();
		f1.eat();
	}
}

我们知道main方法实际上相当于一个客户端,此时如果想换一个子类,由苹果换成橘子,那么就需要修改main方法。那么怎么避免这个问题呢~~就是在接口和子类之间加一个过渡端,通过该客户端还获得具体是哪一个接口实例。如下:

2.使用工厂设计模式的程序

interface Fruit{
	public void eat();
}

class Apple implements Fruit{
	@Override
	public void eat() {
		System.out.println("吃苹果。");
	}
}

class Orange implements Fruit{
	@Override
	public void eat() {
		System.out.println("吃橘子。");
	}
}
//工厂类
class Factory{
	public static Fruit getInstance(String className) {
		Fruit f = null;
		//注意:比较字符串相等时,把字符串常量放前边可以避免空指针异常。
		if("apple".equalsIgnoreCase(className)) { 
			f = new Apple();
		}
		if("orange".equalsIgnoreCase(className)) {
			f = new Orange();
		}
		return f;
	}
}
public class Test {
	public static void main(String args[]) {
		Fruit f = Factory.getInstance(args[0]);//随便传参数
		if(f != null) {
			f.eat();
		}else {
			System.out.println("我们没有这种东西可以吃。");
			System.exit(1);
		}
	}
}

此时客户端就可以直接输入一个参数,然后通过Factory类自动找到具体实例喽。

二、代理设计

1.概念:

所谓代理设计,就是指用代理主题来操作真实主题,真实主题执行具体的业务操作,代理主题负责处理其他相关业务。

比如:客户端使用代理上网。客户端通过代理连接网络时,由代理服务器完成用户权限或访问限制等,而真实服务器只需要提供客户端访问的网页即可。

2.代理设计实现:

//network接口
interface Network{
	//抽象的上网操作
	public void browse();
}
//真实主题
class Real implements Network{
	//真实的上网操作
	@Override
	public void browse() {
		System.out.println("浏览真实网页信息。");
	}
}
//代理主题
class Proxy implements Network{
	//定义一个network接口
	private Network network;
	//构造器
	public Proxy(Network network) {
		this.network = network;
	}
	//其他相关业务
	public void check() {
		System.out.println("检查用户是否合法。");
	}
	//代理的上网操作,要完成其他相关业务。
	@Override
	public void browse() {
		this.check();//调用处理相关业务的方法
		this.network.browse();//调用真实上网操作!!!
	}
}

public class Test {
	public static void main(String args[]) {
		Network net = null;
		net = new Proxy(new Real());//通过构造器实例化代理,同时传入代理的真实操作。
		net.browse();//客户端只关心上网浏览,没考虑用户合法化检查等其他业务。
	}
}

三、适配器设计

1.概念:

已知一个类要实现一个接口,就要实现接口的全部抽象方法。可是如果此类用不到全部的抽象方法呢?此时就需要一个中间的过渡,但是此过渡类不想被直接使用,那么我们就可以将此过渡类定义为抽象类,并在其中实现若干方法(方法体为空),称该过渡类为适配器。之后只要实现该抽象类并重写有用的方法即可啦。

2.适配器设计实现:

//接口
interface Window{
	void open();//打开窗口
	void close();//关闭窗口
	void activated();//窗口活动
	void iconified();//窗口最小化
	void deiconified();//窗口恢复大小
}
//适配器,包含接口中的全部方法。
abstract class WindowAdapter implements Window{
	public void open() {};
	public void close() {};
	public void activated() {};
	public void iconified() {};
	public void deiconified() {};
}
//具体实现类,只包含需要的方法
class WindowImpl extends WindowAdapter{
	public void open() {
		System.out.println("打开窗口。");
	}
	public void close() {
		System.out.println("关闭窗口。");
	}
}

public class Test {
	public static void main(String args[]) {
		Window win = new WindowImpl();
		win.open();
	}
}

适配器模式在涉及图形界面时会被大量使用。

四、观察者设计模式

1.什么叫观察者:

2.实现:

java.util中提供Observable类和Observer接口,使用它们可完成观察者模式。

1)被观察的类必须继承Observable类,Observable类常用方法如下:

2)每个观察者都要实现Observer接口,Observer接口只有一个.update()方法。

示例:每个购房者都在观察房价的变化,一旦房价发生变化,所有观察者都会立刻有所行动。

//被观察的类
class House extends Observable{
	private float price;
	
	public House(float price) {
		this.price = price;
	}

	public void setPrice(float price) {
		super.setChanged();//设置变化点
		super.notifyObservers(price);//通知所有观察者价格改变
		this.price = price;
	}
	
	public String toString() {
		return "房价为:"+ this.price;
	}
}

//观察者类
class HousePriceObserver implements Observer{
	private String name;
	public HousePriceObserver(String name) {
		this.name = name;
	}

	public void update(Observable o, Object arg) {
		if(arg instanceof Float) {
			System.out.print(this.name + "观察到价格变为:");
			System.out.println(((Float) arg).floatValue());
		}
	}
}

public class Demo {
	public static void main(String args[]){
		House house = new House(100000);
		HousePriceObserver hpo1 = new HousePriceObserver("观察者A");
		HousePriceObserver hpo2 = new HousePriceObserver("观察者B");
		HousePriceObserver hpo3 = new HousePriceObserver("观察者C");
		house.addObserver(hpo1);//加入观察者
		house.addObserver(hpo2);
		house.addObserver(hpo3);
		System.out.println(house);//输出房价
		house.setPrice(200000);//更改房价
		System.out.println(house);//输出新房价
	}
}


//运行结果:
//房价为:100000.0
//观察者C观察到价格变为:200000.0
//观察者B观察到价格变为:200000.0
//观察者A观察到价格变为:200000.0
//房价为:200000.0

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值