结构型模式
类或者对象按照一定布局组成更大的对象。类结构模式采用继承接口,对象模式采用组合或聚合来组合对象。
结构型模式中除了适配器外,其余都是对象模式
一、代理模式
- 代理模式在客户端和目标对象之间起到中介和保护作用
- 优点:中介可以扩展目标对象功能、解耦
- 缺点:增加代理影响性能,增加复杂度
抽象主题 Abstract Subject
接口或者抽象类定义真实主题和代理对象实现的方法
interface AbstractSubject{
void request();
}
真实主题 Concrete subject
实现抽象主题具体接口
class ConcreteSubject implement AbstractSubject{
void request(){
System.out.println("处理请求");
}
}
代理类 Proxy
提供真实主题相同的接口,内部包括真实主题的引用,可以访问、控制、扩展真实主题功能。
class Proxy implements AbstractSubject{
private ConcreteSubject realSub;
public request(){
if(null==realSub){
realSub=new ConcreteSubject();
}
preRequest();
realSub.request();
posRequest();
}
private void preRequest(){
System.out.println("调用前");
}
private void PosRequest(){
System.out.println("调用后");
}
}
调用类
class TestProxy{
public static void mian(String[] args){
Proxy pro=new Proxy();
pro.request();
}
}
代理模式扩展-动态代理 DynamicProxy
JDK动态代理依赖接口,可以没有实现类
抽象主题
interface AbstractDynamicSubject{
void request();
}
真实主题
class DynamicSubject implements AbstractDynamicSubject{
void request(){
System.out.println("dynamicSubject");
}
}
执行处理类 InvocationHandler
class MyInvocationHandler implements InvocationHandler{
@Override
public Object invok(Object proxy,Method method,Object[] arg) throw ThrowAble{
System.out.print("testDynamicProxy");
return null;
}
}
调用类
public class TestDynamicProxy{
public static void main(String[] args){
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
AbstractDynamicSubject proxySubject= (AbstractDynamicSubject) Proxy.newProxyInstance(DynamicSubject.class.getClassLoad(),DynamicSubject
.class.getInterfaces(),new MyInvocationHandler());
}
}
二、适配器模式
将类的接口转换为客户希望的另一个接口,分为类结构模型和对象结构模型,类需要了解组件内部细节较少使用
适用老的接口使用,第三方接口匹配
目标 target
interface Target{
void request();
}
(被)适配者 Adaptee
class Adaptee {
void adapteeRequest(){
System.out.println("adaptee");
}
}
适配器(类) ClassAdapter
class ClassAdapter extends Adaptee implements Target{
void request(){
adapteeRequest();
}
}
对象适配器 ObjectAdapter
class ObjectAdapter implements Target{
private Adaptee ad;
Public ObjectAdapter(Adaptee cad){
ad=cad;
}
void request(){
ad.adapteeRequest();
}
}
调用类
public class TestAdapter{
public void static main(String[] args){
Target oba=new ObjectAdapter(new ClassAdapter());
oba.request();
}
}
扩展,双向适配器
interface Adpteeinf {
void adpteeRequest();
}
class TwoObjectAdapter implements Adpteeinf,Target{
private Adaptee da;
private Target tg;
public TwoObjectAdapter(Adaptee cda){
da=cda;
}
public TwoObjectAdapter(Target tga){
tg=tga;
}
void request(){
da.adapteeRequest();
}
void adapteeRequest(){
tg.request();
}
}
三、桥接模式
将抽象和实现分离,使其独立变化。用组合关系代替集成关系来实现,降低了抽象和实现两个可变维度耦合度。
当一个类有两种独立的变化维度,且都需要扩展,例如包有颜色、用途两种维度属性,且都需要扩展变化。
实现化角色 implementor
interface Implementor {
void operation();
}
具体实现化角色 ConcreterImplement
class ConcreteImplement implements Implementor{
void operation(){
System.out.print("concrete");
}
}
抽象化角色 Abstraction
abstract Abstraction{
private Implementor imp;
public Abstraction(Implementor imp){
this.imp=imp;
}
void operationImp();
}
扩展抽象化角色
class ReAbstraction extends Abstraction{
public ReAbstraction(Implementor imp){
super(imp);
}
public void operationImp(){
imp.operation();
System.out.print("Reimp");
}
}
调用类
public class TestBridge{
public static void main(String[] args){
Implementor imp= new ConcreteImplement();
ReAbstraction reAb=new ReAbstraction(imp);
reAb.operationImp;
}
}
模式扩展
有时桥接模式可与适配器模式联合使用。
四、装饰模式 decorator
不改变现有结构的情况下,动态增加职责功能。最著名的应用java中的I/O 设计
例如,Reader增加缓冲区
BufferedReader in =new BufferedReader(new FileReader("D:\t.text"));
String s=in.readLine();
抽象构件 Component
定义接口规范需要附加职责的对象
interface Component{
void read();
}
抽象构件的实现 ConcreteComponent
class ConcreteComponent implements Component{
void read(){
System.out.println("read");
}
}
抽象裝飾 AbstractDecorator
定义需要扩展的功能,由子类集成实现
abstract Decorator implements Component{
private Component cp;
public Decorator(Component cp){
this.cp=cp;
}
void read(){
cp.read();
}
}
具体抽象装饰类 ConcreteDecorator
class ConcreteDecorator extends Decorator{
public ContreteDecorator(Component cp){
super(cp);
}
void read(){
super.read();
addFn();
}
private addFn(){
System.out.print("扩展功能");
}
}
五、外观模式 facade
为多个子系统提供统一个一致的接口,方便外部访问。
降低了子系统与客户端直接的耦合,是子系统的变化不会影响调用。减少了对象
处理的数目
新增子系统需要修改外观类和客户端,违背了开闭原则。
外观角色 Facade
对子系统提供统一的接口
class Facade{
private SubSys1 s1=new SubSys1();
private SubSys2 s2 =new SubSys2();
void method(){
s1.method1();
s2.method2();
}
}
子系统 SubSystem
class SubSys1{
void method1{
System.out.println("print1()");
}
}
class SubSys2{
void method2{
System.out.println("print2()");
}
}
客户端 TestFacade
class TestFacade{
public static void main(String[] args){
Facade fe=new Facade();
fe.method();
}
}
六、享元模式 Flyweight
运用共享的技术来有效支撑,大量颗粒度的对象复用。
抽象享元角色 Flyweight
规范要实现的公共接口,非享元通过接口参数传入。
interface Flyweight{
void setUnFlyweight(UnFlyweight uflyweight);
}
具体享元角色 ConcreteFlyweight
class ConcreteFlyweight implements Flyweight{
private String key;
public ConcreteFlyweight(String key){
this.key=key;
}
public void setUnflyweight(Unflyweight uflyweight){
System.out.println("具体享元被调用");
System.out.println("非享元信息是"+uflyweight.info());
}
}
非享元角色 UnsharedFlyweight
class UnshareFlyweight{
String info;
public UnshareFlyweight(String info){
this.info=info;
}
public String getInfo(){
return info;
}
pblic void setInfo(String info){
this.info=info;
}
}
享元工厂角色 FlyweightFactory
负责创建和管理享元角色。客户请求时返回原有对象或创建新对象。
class FlyweightFactory{
private HashMap<String,Flyweight> flyweights=new HashMap<>();
public getFlyweight(String key){
Flyweight flyweight=flyweights.get(key);
if(null==flyweight){
flyweight =new ConcreteFlyweight(key);
flyweights.put(key,flyweight);
}
return flyweight;
}
}
享元模式扩展
单纯享元模式 、符合享元模式
复合享元模式 CompositeConcreteFlyweight
public class CompositeCOncreteFlyweight implements Flyweight{
private List<FLyweight> flyweights=new ArraryList<>();
void setFlyweight(UnFlyweight uFlyweight){
System.out.println(uFLyweight.getInfo());
}
public addFlyweight(Flyweight flyweight){
flyweights.add(flyweight);
}
public removeFlyweight(Flyweight flyweight){
flyweights.remove(flyweight);
}
}
七、组合模式 Composite
将对象组合成树状层次结构的模式,客户端可以一致底处理单个对象或组合。分为透明式和安全式
安全式为例:
抽象构件 Component
abstract Component{
void operat();
}
树叶构件角色 Leaf
class Leaf implements Component{
void operat(){
System.out.print("leaf");
}
}
树枝构件 Composite
class Commposite implements Component{
private ArrayList<Component> leafs =new ArrayList<>();
void operat(){
for(Component leaf:leafs)
System.out.print("composite");
}
public addLeaf(Leaf leaf){
leafs.add(leaf);
}
pbulic remove(Leaf leaf){
leafs.remove(leaf);
}
public List<Component> getChild(){
return leafs;
}
}