一、工厂设计
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