代理模式
public interface FoodService {
Food makeChicken();
Food makeNoodle();
}
public class FoodServiceImpl implements FoodService {
public Food makeChicken() {
Food f = new Chicken()
f.setChicken("1kg");
f.setSpicy("1g");
f.setSalt("3g");
return f;
}
public Food makeNoodle() {
Food f = new Noodle();
f.setNoodle("500g");
f.setSalt("5g");
return f;
}
}
public class FoodServiceProxy implements FoodService {
// 也可以通过构造方法注入
private FoodService foodService = new FoodServiceImpl();
public Food makeChicken() {
Food food = foodService.makeChicken();
// 增强
food.addCondiment("Add more chili");
return food;
}
public Food makeNoodle() {
Food food = foodService.makeNoodle();
return food;
}
}
客户端调用
FoodService foodService = new FoodServiceProxy();
foodService.makeChicken();
代理模式说白了就是做 “方法包装” 或做 “方法增强”。在面向切面编程中,其实就是动态代理的过程。比如 Spring 中,我们不定义代理类,但是 Spring 会帮我们动态来定义代理,然后把我们定义在 @Before、@After、@Around 中的代码逻辑动态添加到代理中
Spring 中实现动态代理有两种,一种是如果我们的类定义了接口,如 UserService 接口和 UserServiceImpl 实现,采用 JDK 的动态代理,另一种是没有定义接口,Spring 会采用 CGLIB 进行动态代理
适配器模式
适配器模式做的就是,有一个接口需要实现,但是现成的对象都不满足,需要加一层适配器来进行适配。
适配器模式总体来说分三种:默认适配器模式、对象适配器模式、类适配器模式
默认适配器模式
// Appache commons-io 包中的 FileAlterationListener
// 用于对文件或文件夹进行监控
public interface FileAlterationListener {
void onStart(final FileAlterationObserver observer);
void onDirectoryCreate(final File directory);
void onDirectoryChange(final File directory);
void onDirectoryDelete(final File directory);
void onFileCreate(final File file);
void onFileChange(final File file);
void onFileDelete(final File file);
void onStop(final FileAlterationObserver observer);
}
问题就是抽象方法太多了,如果我们要用这个接口,我们要实现每一个抽象方法,但如果我们只是想要其中的一两个方法,我们还是不得不实现所有的方法。
所以,需要下面的一个适配器,它用于实现上面的接口,但是所有的方法都是空方法,这样,我们就可以转而定义自己的类来继承下面这个类
public class FileAlterationListenerAdaptor implements FileAlterationListener {
public void onStart(final FileAlterationObserver observer) {}
public void onDirectoryCreate(final File directory) {}
public void onDirectoryChange(final File directory) {}
public void onDirectoryDelete(final File directory) {}
public void onFileCreate(final File file) {}
public void onFileChange(final File file) {}
public void onFileDelete(final File file) {}
public void onStop(final FileAlterationObserver observer) {}
}
我们可以定义以下类,只需要实现想实现的方法就可以
public class FileMonitor extends FileAlterationListenerAdaptor {
public void onFileCreate(final File file) {
// 文件创建
doSomething();
}
public void onFileDelete(final File file) {
// 文件删除
doSomething();
}
}
对象适配器模式
将鸡适配成鸭,鸡也能当鸭来用。因为现在鸭这个接口,没有合适的实现类可以用,所以需要适配器。
public interface Duck {
public void quack();
public void fly();
}
public interface Cock {
public void gobble();
public void fly();
}
public class WildCock implements Cock {
public void gobble() {
System.out.println("叫");
}
public void fly() {
System.out.println("飞");
}
}
鸭接口有 fly() 和 quare() 两个方法,鸡如果要冒充鸭,fly() 方法是有的,但是鸡没有 quack() 方法
public class CockAdapter implements Duck {
Cock cock;
public CockAdapter(Cock cock) {
this.cock = cock;
}
// 实现鸭方法
@Override
public void quack() {
// 内部其实是cock
cock.gobble();
}
@Override
public void fly() {
cock.fly();
}
}
客户端调用
public static void main(String[] args) {
Cock wildCock = new WildCock();
Duck duck = new CockAdapter(wildCock);
}
类适配器模式
通过继承实现,自动获得了所需要的大部分方法
类适配和对象适配的区别和相同点
一个采用继承,一个采用组合;
类适配属于静态实现,对象适配属于组合的动态实现,对象适配需要多实例化一个对象。对象适配用得比较多。
桥梁模式
public interface DrawAPI {
public void draw(int radius, int x, int y);
}
// 实现类
public class RedPen implements DrawAPI {
@Override
public void draw(int radius, int x, int y) {
System.out.println("用红色笔画图,radius:" + radius + ", x:" + x + ", y:" + y);
}
}
public class GreenPen implements DrawAPI {
@Override
public void draw(int radius, int x, int y) {
System.out.println("用绿色笔画图,radius:" + radius + ", x:" + x + ", y:" + y);
}
}
public class BluePen implements DrawAPI {
@Override
public void draw(int radius, int x, int y) {
System.out.println("用蓝色笔画图,radius:" + radius + ", x:" + x + ", y:" + y);
}
}
抽象类,该类的实现类都需要使用 DrawAPI
public abstract class Shape {
protected DrawAPI drawAPI;
protected Shape(DrawAPI drawAPI) {
this.drawAPI = drawAPI;
}
public abstract void draw();
}
// 抽象类子类
// 圆形
public class Circle extends Shape {
private int radius;
public Circle(int radius, DrawAPI drawAPI) {
super(drawAPI);
this.radius = radius;
}
public void draw() {
drawAPI.draw(radius, 0, 0);
}
}
// 长方形
public class Rectangle extends Shape {
private int x;
private int y;
public Rectangle(int x, int y, DrawAPI drawAPI) {
super(drawAPI);
this.x = x;
this.y = y;
}
public void draw() {
drawAPI.draw(0, x, y);
}
}
客户端调用
public static void main(String[] args) {
Shape greenCircle = new Circle(10, new GreenPen());
Shape redRectangle = new Rectangle(4, 8, new RedPen());
greenCircle.draw();
redRectangle.draw();
}
优点:非常容易进行扩展。