- 适配器模式、
- 装饰器模式、
- 代理模式、
- 外观模式、
- 桥接模式、
- 组合模式、
- 享元模式
适配器模式
- 即定义一个包装类,用于包装不兼容接口的对象
包装类 = 适配器Adapter;
类的适配器模式是把适配的类的API转换成为目标类的API - 适配器模式的形式分为:类的适配器模式和对象的适配器模式
类的适配器模式
public interface Target {
//这是源类Adapteee没有的方法
public void Request();
}
public class Adaptee {
public void SpecificRequest(){
}
}
//适配器Adapter继承自Adaptee,同时又实现了目标(Target)接口。
public class Adapter extends Adaptee implements Target {
//目标接口要求调用Request()这个方法名,但源类Adaptee没有方法Request()
//因此适配器补充上这个方法名
//但实际上Request()只是调用源类Adaptee的SpecificRequest()方法的内容
//所以适配器只是将SpecificRequest()方法作了一层封装,封装成Target可以调用的Request()而已
@Override
public void Request() {
this.SpecificRequest();
}
}
public class AdapterPattern {
public static void main(String[] args){
Target mAdapter = new Adapter();
mAdapter.Request();
}
}
对象的适配器模式
与类的适配器模式不同的是,对象的适配器模式不是使用继承关系连接到Adaptee类,而是使用委派关系连接到Adaptee类。
public interface Target {
//这是源类Adapteee没有的方法
public void Request();
}
public class Adaptee {
public void SpecificRequest(){
}
}
class Adapter implements Target{
// 直接关联被适配类
private Adaptee adaptee;
// 可以通过构造函数传入具体需要适配的被适配类对象
public Adapter (Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void Request() {
// 这里是使用委托的方式完成特殊功能
this.adaptee.SpecificRequest();
}
}
public class AdapterPattern {
public static void main(String[] args){
//需要先创建一个被适配类的对象作为参数
Target mAdapter = new Adapter(new Adaptee());
mAdapter.Request();
}
}
装饰器模式
动态地给一个对象添加一些额外的职责。就增加功能来说,相比生成子类更为灵活。
装饰器(Decorator)模式,是一种在运行期动态给某个对象的实例增加功能的方法。
public interface TextNode {
// 设置text:
void setText(String text);
// 获取text:
String getText();
}
public class SpanNode implements TextNode {
private String text;
public void setText(String text) {
this.text = text;
}
public String getText() {
return "<span>" + text + "</span>";
}
}
public abstract class NodeDecorator implements TextNode {
protected final TextNode target;
protected NodeDecorator(TextNode target) {
this.target = target;
}
public void setText(String text) {
this.target.setText(text);
}
}
public class BoldDecorator extends NodeDecorator {
public BoldDecorator(TextNode target) {
super(target);
}
public String getText() {
return "<b>" + target.getText() + "</b>";
}
}
代理模式
- 静态代理
https://blog.csdn.net/carson_ho/article/details/54910472
给目标对象提供一个代理对象,并由代理对象控制对目标对象的引用
public interface Subject {
public void buyMac();
}
public class RealSubject implement Subject{
@Override
public void buyMac() {
System.out.println(”买一台Mac“);
}
}
public class Proxy implements Subject{
@Override
public void buyMac{
//引用并创建真实对象实例,即”我“
RealSubject realSubject = new RealSubject();
//调用真实对象的方法,进行代理购买Mac
realSubject.buyMac();
//代理对象额外做的操作
this.WrapMac();
}
public void WrapMac(){
System.out.println(”用盒子包装好Mac“);
}
}
public class ProxyPattern {
public static void main(String[] args){
Subject proxy = new Proxy();
proxy.buyMac();
}
}
- 动态代理
动态代理(Dynamic Proxy),可以在运行期动态创建某个interface的实例
静态(编写实现类)
public interface Hello {
void morning(String name);
}
public class HelloWorld implements Hello {
public void morning(String name) {
System.out.println("Good morning, " + name);
}
}
Hello hello = new HelloWorld();
hello.morning("Bob");
动态
interface Hello {
void morning(String name);
}
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method);
if (method.getName().equals("morning")) {
System.out.println("Good morning, " + args[0]);
}
return null;
}
};
Hello hello = (Hello) Proxy.newProxyInstance(
Hello.class.getClassLoader(), // 传入ClassLoader
new Class[] { Hello.class }, // 传入要实现的接口
handler); // 传入处理调用方法的InvocationHandler
hello.morning("Bob");
}
}
外观模式
https://www.jianshu.com/p/1b027d9fc005
通过创建一个统一的外观类,用来包装子系统中一个 / 多个复杂的类,客户端可通过调用外观类的方法来调用内部子系统中所有方法
//灯类
public class SubSystemA_Light {
public void on(){
System.out.println("打开了灯....");
}
public void off(){
System.out.println("关闭了灯....");
}
}
//电视类
public class SubSystemB_Television {
public void on(){
System.out.println("打开了电视....");
}
public void off(){
System.out.println("关闭了电视....");
}
}
//空调类
public class SubSystemC_Aircondition {
public void on(){
System.out.println("打开了电视....");
}
public void off(){
System.out.println("关闭了电视....");
}
}
public class Facade Pattern{
public static void main(String[] args){
{
SubSystemA_Light light = new SubSystemA_Light();
SubSystemB_Television television = new SubSystemB_Television();
SubSystemC_Aircondition aircondition = new SubSystemC_Aircondition();
//起床后开电器
System.out.prinln("起床了");
light.on();
television.on();
aircondition.on();
System.out.prinln("可以看电视了");
//睡觉时关电器
System.out.prinln("睡觉了");
light.off();
television.off();
aircondition.off();
System.out.prinln("可以睡觉了");
}
}
public class Facade{
SubSystemA_Light light;
SubSystemB_Television television ;
SubSystemC_Aircondition aircondition;
//传参
public Facade(SubSystemA_Light light,SubSystemB_Television television,SubSystemC_Aircondition aircondition){
this.light = light;
this.television = television ;
this.aircondition =aircondition;
}
//起床后一键开电器
public void on{
System.out.prinln("起床了");
light.on();
television.on();
aircondition.on();
}
//睡觉时一键关电器
System.out.prinln("睡觉了");
light.off();
television.off();
aircondition.off();
}
}
public class Facade Pattern{
public static void main(String[] args){
{
//实例化电器类
SubSystemA_Light light = new SubSystemA_Light();
SubSystemB_Television television = new SubSystemB_Television();
SubSystemC_Aircondition aircondition = new SubSystemC_Aircondition();
//传参
Facade facade = new Facade(light,television,aircondition);
//客户端直接与外观对象进行交互
facade.on;
System.out.prinln("可以看电视了");
facade.off;
System.out.prinln("可以睡觉了");
}
组合模式
https://www.jianshu.com/p/685dd6299d96
在计算机文件系统中,有文件夹的概念,文件夹里面既可以放入文件也可以放入文件夹,但是文件中却不能放入任何东西。文件夹和文件构成了一种递归结构和容器结构。把文件夹和文件统称为目录条目,(directory entry)
package Composite;
public abstract class Entry {
public abstract String getName();
public abstract int getSize();
public Entry add(Entry entry) throws FileTreatMentException {
throw new FileTreatMentException();
}
public void printList() {
printList("");
}
protected abstract void printList(String prefix);
public String toString() {
return getName() + "(" + getSize() + ")";
}
}
package Composite;
public class File extends Entry {
private String name;
private int size;
public File(String name, int size) {
this.name = name;
this.size = size;
}
@Override
public String getName() {
return name;
}
@Override
public int getSize() {
return size;
}
@Override
protected void printList(String prefix) {
System.out.println(prefix + '/' + this);
}
}
package Composite;
import java.util.ArrayList;
import java.util.Iterator;
public class Directory extends Entry {
private String name;
private ArrayList directory = new ArrayList();
public Directory(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public int getSize() {
int size = 0;
Iterator it = directory.iterator();
while(it.hasNext()) {
Entry entry = (Entry)it.next();
size += entry.getSize();
}
return size;
}
public Entry add(Entry entry) {
directory.add(entry);
return this;
}
@Override
protected void printList(String prefix) {
System.out.println(prefix + "/" + this);
Iterator it = directory.iterator();
while(it.hasNext()) {
Entry entry = (Entry)it.next();
entry.printList(prefix + "/" + name);
}
}
}
享元模式
享元(Flyweight)的核心思想很简单:如果一个对象实例一经创建就不可变,那么反复创建相同的实例就没有必要,直接向调用方返回一个共享的实例就行,这样即节省内存,又可以减少创建对象的过程,提高运行速度。
Integer.valueOf()这个静态工厂方法创建Integer实例,当传入的int范围在-128~+127之间时,会直接返回缓存的Integer实例:
static final int low = -128;
static final int high=127;
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
public static void main(String[] args) throws InterruptedException {
Integer n1 = Integer.valueOf(100);
Integer n2 = Integer.valueOf(100);
System.out.println(n1 == n2); // true
}
我们以Student为例,设计一个静态工厂方法,它在内部可以返回缓存的对象:
public class Student {
// 持有缓存:
private static final Map<String, Student> cache = new HashMap<>();
// 静态工厂方法:
public static Student create(int id, String name) {
String key = id + "\n" + name;
// 先查找缓存:
Student std = cache.get(key);
if (std == null) {
// 未找到,创建新对象:
System.out.println(String.format("create new Student(%s, %s)", id, name));
std = new Student(id, name);
// 放入缓存:
cache.put(key, std);
} else {
// 缓存中存在:
System.out.println(String.format("return cached Student(%s, %s)", std.id, std.name));
}
return std;
}
private final int id;
private final String name;
public Student(int id, String name) {
this.id = id;
this.name = name;
}
}
网友评论