1、制定标准
接口是标准,所谓的标准,指的是各方共同遵守的一个守则。只要操作标准统一了,所有的参与者才可以按照统一的规则操作。
如在电脑以及各个设备的连接上,USB就是一个操作标准,那么下面通过代码来验证以上的操作:
package interface_usb;
interface USB { // 定义USB接口的标准
public void work(); // 拿到usb设备就表示要进行工作
}
class Computer {
public void plugin(USB usb) {
usb.work(); // 按照固定的方式进行工作
}
}
class Printer implements USB { // 打印机实现了USB接口标准
public void work() {
System.out.print("打印机用USB接口,连接开始工作。");
}
}
class Flash implements USB { // U盘实现USB接口标准
public void work() {
System.out.print("U盘用USB接口,连接开始工作。");
}
}
public class InterfaceStandards {
public static void main(String[] args) {
Computer c = new Computer();
c.plugin(new Printer()); // 在电脑上使用打印机
c.plugin(new Flash()); // 在电脑上使用U盘
}
}
【结果】
按照固定的USB接口标准,可以定义无数多个子类,并且这无数多个子类,都可以在电脑上插入使用。
按照以上的方式不管有多少个设备,电脑上支持度都是一样,所以现在的USB提供的就是一个操作标准。
2、工厂设计模式
在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的。但是在一些情况下,new操作符直接生成对象会带来一些问题。
举例来说,许多类型对象的创造需要一系列的步骤。你可能需要计算或取得对象的初始设置;选择生成哪个子对象实例;或在生成你需要的对象之前必须先生成一些辅助功能的对象。
在这些情况, 新对象的建立就是一个“过程”,不仅是一个操作,像一部大机器中的一个齿轮传动。
如何能轻松地建立这么“复杂”的对象即操作中不需要粘贴复制呢?建立一个工厂来创建新的对象。
在此之前先来看一个示例:
interface Fruit { // 定义一个水果标准
public void eat();
}
class Apple implements Fruit {
public void eat() {
System.out.print("吃苹果");
}
}
class Orange implements Fruit {
public void eat() {
System.out.print("吃橘子");
}
}
public class SimpleExample {
public static void main(String[] args) {
Fruit f = new Apple(); //初始化参数
f.eat();
}
}
此例中发现在主类(客户端)之中直接让一个具体的子类和一个接口绑定在一起,那么如果要修改使用的子类,对于程序而言,就意味着要修改客户端。所以此时程序之中就出现了接口和子类的耦合问题,为解决这一问题,使用工厂模式。
interface Fruit { // 定义一个水果标准
public void eat();
}
class Apple implements Fruit {
public void eat() {
System.out.print("吃苹果");
}
}
class Orange implements Fruit {
public void eat() {
System.out.print("吃橘子");
}
}
// 所有的接口对象都通过Factory类来取得
class Factory { // 此类不需要维护属性的状态
public static Fruit getInstance(String className) {
if("apple".equals(className)) {
return new Apple();
}
if("orange".equals(className)) {
return new Orange();
}
return null;
}
}
public class InterfaceFactory {
public static void main(String[] args) {
Fruit f = Factory.getInstance("apple"); //初始化参数
f.eat();
}
}
【结果】
此时的程序,客户端没有和具体的子类耦合在一起,这样一来,如果再有更多的Fruit接口子类出现,只需要修改Factory类即可,即:所有的接口对象都通过Factory类取得。在程序员自己开发的代码之中,只要是遇见了取得接口对象实例的操作,都应该采用工厂设计模式。
3、代理设计模式
代理模式:给某一对象提供代理对象,并由代理对象控制具体对象的引用。代理,指的就是一个角色代表另一个角色采取行动。
就像生活中,一个红酒厂商是不会直接把红酒零售给客户的,都是通过代理来完成他的销售业务的。而客户也不用为了喝红酒而到处找工厂,他只要找到厂商在当地的代理就行了,具体红酒工厂在那里,客户不用关心,代理会帮他处理。
这里产生了四个对象:客户、代理商、红酒厂商、代理商-红酒厂商(关系)。
代理模式作用:为其他对象(红酒厂商)提供一种代理(代理商)以控制对这个对象(红酒厂商)的访问。
代理对象可以在客户端(客户)和目标对象(红酒厂商)之间起到中介作用。
如下例:
package proxy_test;
abstract class Subject { // 代理请求
abstract public void request();
}
class RealSubject extends Subject { // 真实角色
@Override
public void request() {
System.out.print("我是红酒厂商,欢迎品尝购买!");
}
}
class ProxySubject extends Subject { // 代理角色
private RealSubject realSubject; //真实角色作为代理角色的属性
public void request() { // 该方法封装了真实对象的request方法
preRequest();
if(realSubject == null) {
realSubject = new RealSubject();
}
realSubject.request(); // 此处执行真实对象的request方法
postRequest();
}
private void preRequest() {
System.out.print("广告宣传,免费品尝!");
}
private void postRequest() {
System.out.print("付款购买!");
}
}
public class ProxyTest {
public static void main(String[] args) { // 客户直接找代理商
Subject sub = new ProxySubject();
sub.request();
}
}
【结果】
代理设计模式的核心组成:一个接口有两个子类,一个子类负责真实的业务操作功能,另外一个子类负责完成与真实业务有关的操作。