大家好,我是码农老吴,欢迎收看极客架构师推出的架构师书房栏目。今天,我继续给大家解读《代码不朽》这本书。
上期,我们分享了,拆分过大类的方法,根据不同关注点拆分类(Split Classes to Separate Concerns),本期,我们看另外一个策略,隐藏接口背后的特定实现(Hide Specialized Implementations Behind Interfaces),目的是达到模块之间的解耦和。
这个案例代码,说的是一个移动app项目,里面的DigitalCamera类,用于提供相机的相关操作,比如拍照,打开闪光灯,关闭闪光灯等功能。另外一个类SmartphoneApp,是DigitalCamera类的调用方,或者叫客户方,依赖DigitalCamera类。我们看看在项目发展中,出现的问题。
package eu.sig.training.ch06.digitalcamera;
import java.awt.Image;
import java.awt.image.BufferedImage;
// tag::DigitalCamera[]
public class DigitalCamera {
public Image takeSnapshot() {
// ...
// end::DigitalCamera[]
return new BufferedImage(1920, 1080, BufferedImage.TYPE_INT_ARGB);
// tag::DigitalCamera[]
}
public void flashLightOn() {
// ...
}
public void flaslLightOff() {
// ...
}
}
// end::DigitalCamera[]注意,这个类中,建立了DigitalCamera类的对象,所以它依赖DigitalCamera类。
package eu.sig.training.ch06.digitalcamera;
import java.awt.Image;
@SuppressWarnings("unused")
// tag::SmartphoneApp[]
public class SmartphoneApp {
private static DigitalCamera camera = new DigitalCamera();
public static void main(String[] args) {
// ...
Image image = camera.takeSnapshot();
// ...
}
}
// end::SmartphoneApp[]第二次升级,这个类,增加了不少功能,如录制视频,设置定时器,放大缩小等功能。
package eu.sig.training.ch06.advanceddigitalcamera;
import java.awt.Image;
import java.awt.image.BufferedImage;
@SuppressWarnings("unused")
// tag::DigitalCamera[]
public class DigitalCamera {
public Image takeSnapshot() {
// ...
// end::DigitalCamera[]
return new BufferedImage(1920, 1080, BufferedImage.TYPE_INT_ARGB);
// tag::DigitalCamera[]
}
public void flashLightOn() {
// ...
}
public void flaslLightOff() {
// ...
}
public Image takePanoramaSnapshot() {
// end::DigitalCamera[]
return new BufferedImage(1920, 1080, BufferedImage.TYPE_INT_ARGB);
// tag::DigitalCamera[]
// ...
}
public Video record() {
// ...
// end::DigitalCamera[]
return new Video();
// tag::DigitalCamera[]
}
public void setTimer(int seconds) {
// ...
}
public void zoomIn() {
// ...
}
public void zoomOut() {
// ...
}
}
// end::DigitalCamera[]当我们升级了DigitalCamera类的功能之后,对它有直接依赖的SmartphoneApp类,也相应的获得了,访问这些新功能的权限。这可能不是我们所期望的,SmartphoneApp类可能在DigitalCamera类不知情的情况下,使用了新增的功能。如何解决这个问题,就需要使用我们今天分享的技巧,隐藏接口背后的特定实现(Hide Specialized Implementations Behind Interfaces)。
如何理解这句话呢,其实,换种说法,它就是我们平时所说的,面向接口编程。通过接口,来约定双方的职责与权利。具体如何落地,看看作者的做法。
接口及类
SimpleDigitalCamera:抽象产品
DigitalCamera:具体产品
SDK:简单工厂模式
SmartphoneApp:工厂客户方
package eu.sig.training.ch06.simpledigitalcamera;
import java.awt.Image;
// tag::SimpleDigitalCamera[]
public interface SimpleDigitalCamera {
Image takeSnapshot();
void flashLightOn();
void flashLightOff();
}
// end::SimpleDigitalCamera[]package eu.sig.training.ch06.simpledigitalcamera;
import java.awt.Image;
// tag::DigitalCamera[]
public class DigitalCamera implements SimpleDigitalCamera {
// ...
// end::DigitalCamera[]
public Image takeSnapshot() {
return null;
}
public void flashLightOn() {}
public void flashLightOff() {}
// tag::DigitalCamera[]
}
// end::DigitalCamera[]package eu.sig.training.ch06.simpledigitalcamera;
public class SDK {
public static SimpleDigitalCamera getCamera() {
return new DigitalCamera();
}
}package eu.sig.training.ch06.simpledigitalcamera;
import java.awt.Image;
@SuppressWarnings("unused")
// tag::SmartphoneApp[]
public class SmartphoneApp {
private static SimpleDigitalCamera camera = SDK.getCamera();
public static void main(String[] args) {
// ...
Image image = camera.takeSnapshot();
// ...
}
}
// end::SmartphoneApp[]上面的解决方法,就是一个典型的简单工厂模式的应用。这样,SmartphoneApp类,依赖的就仅仅是个接口SimpleDigitalCamera接口,而不是实现类,所以只能访问接口中公开的方法。有关简单工厂模式,我在《架构师基本功之设计模式》中,已经分享过,不了解的朋友可以参考一下。
本期内容我们就分享到这里,下期,我们分享第7章的内容,架构组件的松耦合(Couple Architecture Components Loosely)。
极客架构师,专注架构师成长,我们下期见。
| 留言与评论(共有 0 条评论) “” |