public class Driver extends NonRegisteringDriver implements java.sql.Driver { static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } }
/** * Construct a new driver and register it with DriverManager * @throws SQLException if a database error occurs. */ public Driver() throws SQLException { // Required for Class.forName().newInstance() } }
一个 API 接口监控告警的例子:根据不同的告警规则,触发不同类型的告警。告警支持多种通知渠道,包括:邮件、短信、微信、自动语音电话。通知的紧急程度有多种类型,包括:SEVERE(严重)、URGENCY(紧急)、NORMAL(普通)、TRIVIAL(无关紧要)。不同的紧急程度对应不同的通知渠道。比如,SERVE(严重)级别的消息会通过“自动语音电话”告知相关人员。
public enum NotificationEmergencyLevel { SEVERE, URGENCY, NORMAL, TRIVIAL }
public class Notification { private List<String> emailAddresses; private List<String> telephones; private List<String> wechatIds;
public Notification() {}
public void setEmailAddress(List<String> emailAddress) { this.emailAddresses = emailAddress; }
public void setTelephones(List<String> telephones) { this.telephones = telephones; }
public void setWechatIds(List<String> wechatIds) { this.wechatIds = wechatIds; }
public void notify(NotificationEmergencyLevel level, String message) { if (level.equals(NotificationEmergencyLevel.SEVERE)) { //...自动语音电话 } else if (level.equals(NotificationEmergencyLevel.URGENCY)) { //...发微信 } else if (level.equals(NotificationEmergencyLevel.NORMAL)) { //...发邮件 } else if (level.equals(NotificationEmergencyLevel.TRIVIAL)) { //...发邮件 } } }
//在API监控告警的例子中,我们如下方式来使用Notification类: public class ErrorAlertHandler extends AlertHandler { public ErrorAlertHandler(AlertRule rule, Notification notification){ super(rule, notification); }
@Override public void check(ApiStatInfo apiStatInfo) { if (apiStatInfo.getErrorCount() > rule.getMatchedRule(apiStatInfo.getApi()).getMaxErrorCount()) { notification.notify(NotificationEmergencyLevel.SEVERE, "..."); } } }
public interface MsgSender { void send(String message); }
public class TelephoneMsgSender implements MsgSender { private List<String> telephones;
public TelephoneMsgSender(List<String> telephones) { this.telephones = telephones; }
@Override public void send(String message) { //... }
}
public class EmailMsgSender implements MsgSender { // 与TelephoneMsgSender代码结构类似,所以省略... }
public class WechatMsgSender implements MsgSender { // 与TelephoneMsgSender代码结构类似,所以省略... }
public abstract class Notification { protected MsgSender msgSender;
public Notification(MsgSender msgSender) { this.msgSender = msgSender; }
public abstract void notify(String message); }
public class SevereNotification extends Notification { public SevereNotification(MsgSender msgSender) { super(msgSender); }
@Override public void notify(String message) { msgSender.send(message); } }
public class UrgencyNotification extends Notification { // 与SevereNotification代码结构类似,所以省略... } public class NormalNotification extends Notification { // 与SevereNotification代码结构类似,所以省略... } public class TrivialNotification extends Notification { // 与SevereNotification代码结构类似,所以省略... }
// 装饰器模式的代码结构(下面的接口也可以替换成抽象类) public interface IA { void f(); } public class A implements IA { public void f() { //... } } public class ADecorator implements IA { private IA a; public ADecorator(IA a) { this.a = a; } public void f() { // 功能增强代码 a.f(); // 功能增强代码 } }
public abstract class InputStream { //... public int read(byte b[]) throws IOException { return read(b, 0, b.length); } public int read(byte b[], int off, int len) throws IOException { //... } public long skip(long n) throws IOException { //... }
public int available() throws IOException { return 0; } public void close() throws IOException {}
public synchronized void mark(int readlimit) {} public synchronized void reset() throws IOException { throw new IOException("mark/reset not supported"); }
public boolean markSupported() { return false; } }
public class FilterInputStream extends InputStream { protected volatile InputStream in;
public int read() throws IOException { return in.read(); }
public int read(byte b[]) throws IOException { return read(b, 0, b.length); } public int read(byte b[], int off, int len) throws IOException { return in.read(b, off, len); }
public long skip(long n) throws IOException { return in.skip(n); }
public int available() throws IOException { return in.available(); }
public void close() throws IOException { in.close(); }
public synchronized void mark(int readlimit) { in.mark(readlimit); }
public synchronized void reset() throws IOException { in.reset(); }
public boolean markSupported() { return in.markSupported(); } }
public class BufferedInputStream extends FilterInputStream { protected volatile InputStream in;
// 代理模式的代码结构(下面的接口也可以替换成抽象类) public interface IA { void f(); } public class A impelements IA { public void f() { //... } } public class AProxy implements IA { private IA a; public AProxy(IA a) { this.a = a; } public void f() { // 新添加的代理逻辑 a.f(); // 新添加的代理逻辑 } }
// 装饰器模式的代码结构(下面的接口也可以替换成抽象类) public interface IA { void f(); } public class A implements IA { public void f() { //... } } public class ADecorator implements IA { private IA a; public ADecorator(IA a) { this.a = a; } public void f() { // 功能增强代码 a.f(); // 功能增强代码 } }
InputStream in = new FileInputStream("/user/wangzheng/test.txt"); InputStream bin = new BufferedInputStream(in); DataInputStream din = new DataInputStream(bin); int data = din.readInt();
// 外部系统A public interface IA { //... void fa(); } public class A implements IA { //... public void fa() { //... } } // 在我们的项目中,外部系统A的使用示例 public class Demo { private IA a; public Demo(IA a) { this.a = a; } //... } Demo d = new Demo(new A());
// 将外部系统A替换成外部系统B public class BAdaptor implemnts IA { private B b; public BAdaptor(B b) { this.b= b; } public void fa() { //... b.fb(); } } // 借助BAdaptor,Demo的代码中,调用IA接口的地方都无需改动, // 只需要将BAdaptor如下注入到Demo即可。 Demo d = new Demo(new BAdaptor(new B()));
public class Collections { public static Emueration emumeration(final Collection c) { return new Enumeration() { Iterator i = c.iterator(); public boolean hasMoreElments() { return i.hashNext(); } public Object nextElement() { return i.next(): } } } }
// slf4j统一的接口定义 package org.slf4j; public interface Logger { public boolean isTraceEnabled(); public void trace(String msg); public void trace(String format, Object arg); public void trace(String format, Object arg1, Object arg2); public void trace(String format, Object[] argArray); public void trace(String msg, Throwable t); public boolean isDebugEnabled(); public void debug(String msg); public void debug(String format, Object arg); public void debug(String format, Object arg1, Object arg2) public void debug(String format, Object[] argArray) public void debug(String msg, Throwable t);
//...省略info、warn、error等一堆接口 }
// log4j日志框架的适配器 // Log4jLoggerAdapter实现了LocationAwareLogger接口, // 其中LocationAwareLogger继承自Logger接口, // 也就相当于Log4jLoggerAdapter实现了Logger接口。 package org.slf4j.impl; public final class Log4jLoggerAdapter extends MarkerIgnoringBase implements LocationAwareLogger, Serializable { final transient org.apache.log4j.Logger logger; // log4j public boolean isDebugEnabled() { return logger.isDebugEnabled(); } public void debug(String msg) { logger.log(FQCN, Level.DEBUG, msg, null); } public void debug(String format, Object arg) { if (logger.isDebugEnabled()) { FormattingTuple ft = MessageFormatter.format(format, arg); logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable()); } } public void debug(String format, Object arg1, Object arg2) { if (logger.isDebugEnabled()) { FormattingTuple ft = MessageFormatter.format(format, arg1, arg2); logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable()); } } public void debug(String format, Object[] argArray) { if (logger.isDebugEnabled()) { FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable()); } } public void debug(String msg, Throwable t) { logger.log(FQCN, Level.DEBUG, msg, t); } //...省略一堆接口的实现... }
Provide a unified interface to a set of interfaces in a subsystem. Facade Pattern defines a higher-level interface that makes the subsystem easier to use.
public int countNumOfFiles() { if (isFile) { return 1; } int numOfFiles = 0; for (FileSystemNode fileOrDir : subNodes) { numOfFiles += fileOrDir.countNumOfFiles(); } return numOfFiles; }
public long countSizeOfFiles() { if (isFile) { File file = new File(path); if (!file.exists()) return 0; return file.length(); } long sizeofFiles = 0; for (FileSystemNode fileOrDir : subNodes) { sizeofFiles += fileOrDir.countSizeOfFiles(); } return sizeofFiles; }
public String getPath() { return path; }
public void addSubNode(FileSystemNode fileOrDir) { subNodes.add(fileOrDir); }
public void removeSubNode(FileSystemNode fileOrDir) { int size = subNodes.size(); int i = 0; for (; i < size; ++i) { if (subNodes.get(i).getPath().equalsIgnoreCase(fileOrDir.getPath())) { break; } } if (i < size) { subNodes.remove(i); } } }
public abstract class FileSystemNode { protected String path;
public FileSystemNode(String path) { this.path = path; }
public abstract int countNumOfFiles(); public abstract long countSizeOfFiles();
public String getPath() { return path; } }
public class File extends FileSystemNode { public File(String path) { super(path); }
@Override public int countNumOfFiles() { return 1; }
@Override public long countSizeOfFiles() { java.io.File file = new java.io.File(path); if (!file.exists()) return 0; return file.length(); } }
public class Directory extends FileSystemNode { private List<FileSystemNode> subNodes = new ArrayList<>();
public Directory(String path) { super(path); }
@Override public int countNumOfFiles() { int numOfFiles = 0; for (FileSystemNode fileOrDir : subNodes) { numOfFiles += fileOrDir.countNumOfFiles(); } return numOfFiles; }
@Override public long countSizeOfFiles() { long sizeofFiles = 0; for (FileSystemNode fileOrDir : subNodes) { sizeofFiles += fileOrDir.countSizeOfFiles(); } return sizeofFiles; }
public void addSubNode(FileSystemNode fileOrDir) { subNodes.add(fileOrDir); }
public void removeSubNode(FileSystemNode fileOrDir) { int size = subNodes.size(); int i = 0; for (; i < size; ++i) { if (subNodes.get(i).getPath().equalsIgnoreCase(fileOrDir.getPath())) { break; } } if (i < size) { subNodes.remove(i); } } }
public abstract class FileSystemNode { protected String path;
public FileSystemNode(String path) { this.path = path; }
public abstract int countNumOfFiles(); public abstract long countSizeOfFiles();
public String getPath() { return path; } }
public class File extends FileSystemNode { public File(String path) { super(path); }
@Override public int countNumOfFiles() { return 1; }
@Override public long countSizeOfFiles() { java.io.File file = new java.io.File(path); if (!file.exists()) return 0; return file.length(); } }
public class Directory extends FileSystemNode { private List<FileSystemNode> subNodes = new ArrayList<>();
public Directory(String path) { super(path); }
@Override public int countNumOfFiles() { int numOfFiles = 0; for (FileSystemNode fileOrDir : subNodes) { numOfFiles += fileOrDir.countNumOfFiles(); } return numOfFiles; }
@Override public long countSizeOfFiles() { long sizeofFiles = 0; for (FileSystemNode fileOrDir : subNodes) { sizeofFiles += fileOrDir.countSizeOfFiles(); } return sizeofFiles; }
public void addSubNode(FileSystemNode fileOrDir) { subNodes.add(fileOrDir); }
public void removeSubNode(FileSystemNode fileOrDir) { int size = subNodes.size(); int i = 0; for (; i < size; ++i) { if (subNodes.get(i).getPath().equalsIgnoreCase(fileOrDir.getPath())) { break; } } if (i < size) { subNodes.remove(i); } } }
private Font font; private int size; private int colorRGB;
public Character(char c, Font font, int size, int colorRGB) { this.c = c; this.font = font; this.size = size; this.colorRGB = colorRGB; } }
public class Editor { private List<Character> chars = new ArrayList<>();
public void appendCharacter(char c, Font font, int size, int colorRGB) { Character character = new Character(c, font, size, colorRGB); chars.add(character); } }
public class Editor { private List<Character> chars = new ArrayList<>();
public void appendCharacter(char c, Font font, int size, int colorRGB) { Character character = new Character(c, CharacterStyleFactory.getStyle(font, size, colorRGB)); chars.add(character); } }
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
/** * Cache to support the object identity semantics of autoboxing for values between * -128 and 127 (inclusive) as required by JLS. * * The cache is initialized on first usage. The size of the cache * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option. * During VM initialization, java.lang.Integer.IntegerCache.high property * may be set and saved in the private system properties in the * sun.misc.VM class. */ private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[];
static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h;
cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; }
private static class LongCache { private LongCache(){}
static final Long cache[] = new Long[-(-128) + 127 + 1];
static { for(int i = 0; i < cache.length; i++) cache[i] = new Long(i - 128); } }
public static Long valueOf(long l) { final int offset = 128; if (l >= -128 && l <= 127) { // will cache return LongCache.cache[(int)l + offset]; } return new Long(l); }
下面三种创建对象的方式,推荐使用哪种?
1 2 3
Integer a = new Integer(123); Integer a = 123; Integer a = Integer.valueOf(123);