设计模式学习(三) 结构型 - 代理 装饰 适配器 组合 桥梁 外观 享元

2020年04月27日-

#结构型:

  结构型顾名思义就是讨论的是类和对象的结构。组合接口或实现,或通过组合一些对象实现新的功能。(类结构型、对象结构型)

  简单地说就是 如何将现有类或对象结合在一起形成更加大的结构?

结构型设计模式包含7种:

  代理模式、装饰模式、适配器模式、组合模式、桥梁模式、外观模式、享元模式

#代理模式(Proxy Pattern) Provide a surrogate or placeholder for another object to control access to it.

  代理就像定外卖一样一样的。我让外卖小哥帮我去取餐,这就是代理模式。实现间接的引用。

  优点:减少耦合度、职责清晰、扩展性好。缺点:增加了工作量。

  三个角色:

    抽象主题(Subject)角色:共同接口

    代理主题(Proxy Subject)角色:代理类

    真实主题(Real Subject)角色:真实的 放业务逻辑的类,被代理的类

  用:位于不同的地址空间(比如不同电脑)、或者希望他延迟加载、给代码 不同级别的权限、或需要提供额外的操作、

静态代理:

  接口:

public interface Subject {
    // 请求
    void request();

}

  实际请求的业务逻辑:

public class RealSubject implements Subject {

    public void request() {
        System.out.println("请求成功!");
    }

}

  代理:

public class ProxySubject implements Subject {

    private Subject subject = null;

    public ProxySubject(Subject subject) {
        this.subject=subject;
    }

    public void request() {
        this.beforeRequest();
        subject.request();
        this.afterRequest();
    }

    private void beforeRequest() {
        System.out.println("执行前");
    }

    private void afterRequest() {
        System.out.println("执行后");
    }

}

  测试:

动态代理:一个代理可同时代理多个类

  代理:

public class ProxyInvocation implements InvocationHandler {
    private Object object;

    public ProxyInvocation(Object o) {
        this.object = o;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.println("执行前");
        method.invoke(object,args);
        System.out.println("执行后");
        return object;
    }
}

  测试:

 

 #装饰模式(Decorator Pattern) Attach additional responsibilities to an object dynamically keeping the same interface.Decorators provide a flexible alternative to subclassing for extending functionality.

  向一个现有的对象添加新的功能,同时又不改变其结构。

  优点:继承关系的一个替代方案。画形状的时候不需要知道他的边框颜色是什么要不要加粗 之类的装饰、不管装饰了多少层返回的还是形状。可以做动态的扩展。

   四个角色:

    抽象构件(Component)角色:需要装饰的对象。形状

    具体构件(Concrete Component)角色:圆形

    装饰(Decorator)角色:抽象接口 implements 形状

    具体装饰(Concrete Decorator)角色:蓝色 大小 边框

   抽象构件:

public interface Shape {
    void draw();
}

  具体构建:

public class Circle implements Shape {
    public void draw() {
        System.out.print("Shape Circle");
    }
}

  装饰:

public abstract class Decorator implements Shape {
    private Shape shape;

    public Decorator(Shape shape) {
        this.shape = shape;
    }

    public void draw() {
        shape.draw();
    }
}

  具体装饰:

  蓝色:

public class BlueBorderDecorator extends Decorator {
    public BlueBorderDecorator(Shape shape) {
        super(shape);
    }
    public void draw(){
        super.draw();
        System.out.print(" blue border");
    }
}

  大小:

public class BigSizeDecorator extends Decorator{
    public BigSizeDecorator(Shape shape) {
        super(shape);
    }
    public void draw(){
        super.draw();
        System.out.print(" big size");
    }
}

  测试:

#适配器模式(Adapter Pattern) Convert the interface of a class into another interface clients expect. Adapter letsclasses work together that couldn't otherwise because of incompatible interfaces.

   两个不兼容的接口之间的桥梁。将一个类的接口转换成另外一个接口。

  优点:两个没有任何关系的类在一起运行。

  三个角色:

    目标(Target)角色:v220 220伏

    源(Adaptee)角色:v110 110伏

    适配器(Adapter)角色:Adapter 转换头

 V220:

public interface V220 {

    void charge();// 充电

}

V110:

public class V110 {
    public void charge() {
        System.out.println("110V");
    }
}

Adapter:

public class Adapter implements V220 {

    V110 v110 ;

    public Adapter(V110 v110) {
        super();
        this.v110 = v110;
    }

    public void charge() {
        v110.charge();
    }

}

测试:

 

#组合模式(Composite Pattern) Compose objects into tree structures to represent part-whole hierarchies. Compositelets clients treat individual objects and compositions of objects uniformly

   依据树形结构来组合对象。

  用:树形结构的菜单、文件夹管理

  三个角色:

    抽象构件(Component)角色:抽象接口

    叶子构件(Leaf)角色:叶子

    树枝构件(Composite)角色:树枝

 

抽象:

public interface  Component {

    void operation();// 树枝和叶子节点的共同方法

}

树枝:

public class Composite implements Component {

    private String name;

    private List<Component> list = new ArrayList<Component>();

    public void add(Component component) {
        this.list.add(component);
    }

    public void remove(Component component) {
        this.list.remove(component);
    }

    public List<Component> getChild(){
        return this.list;
    }

    public void display(Composite composite){
        for(Component c:composite.getChild()){
            if(c instanceof Leaf){
                c.operation();
            }else{
                c.operation();
                display((Composite)c);
            }
        }
    }

    public void operation() {
        System.out.println("composite operation");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Composite{" +
                "name='" + name + '\'' +
                ", list=" + list +
                '}';
    }

}

叶子:

public class Leaf implements Component{

    String name;

    public void operation() {
        System.out.println("leaf operation");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Leaf{" +
                "name='" + name + '\'' +
                '}';
    }
}

 测试:

 #桥梁模式(Bridge Pattern) Decouple an abstraction from its implementation so that the two can varyindependently.

   把抽象化与实现化解耦,使得二者可以独立变化.

  四个角色:

    抽象化(Abstraction)角色:它一般是抽象类而不是接口,其中定义了一个Implementor(实现类接口):形状

    修正抽象化(RefinedAbstraction)角色:这里对抽象化角色进行修改。圆形

    实现化(Implementor)角色:实现化接口:颜色

    具体实现化(ConcreteImplementor)角色:具体实现。红色

  优点:解决了继承的缺点、实现了动态耦合、抽象和实现分离。

  用:

形状:

public abstract class Shape {

    Color color;

    public Shape(Color color) {
        this.color = color;
    }

    public abstract void draw();

}

圆形:

public class Circle extends Shape {

    public Circle(Color color) {
        super(color);
    }

    public void draw() {
        System.out.println(super.color.getColor()+"Circle");
    }
}

颜色:

public interface Color {

    String getColor();

}

红色:

public class Red implements Color {

    public String getColor() {
        return "red";
    }

}

测试:

 

# 外观模式(Facade Pattern) Provide a unified interface to a set of interfaces in a subsystem. Facade defines ahigher-level interface that makes the subsystem easier to use.

隐藏系统的复杂性、提供一个访问子系统的接口

优点:减少了系统的相互依赖、安全、灵活。缺点:不符合开闭原则。

适用:子系统相对独立。为复杂的模块提供外界可访问的接口

 

 机票:

public class Ticket {
    public void getTicket(String day){
        System.out.println(day+"机票");
    }
}

车:

public class Car {

    public void getCar(){
        System.out.println("奔驰");
    }
}

酒店:

public class Hotel {

    public void getHotel(){
        System.out.println("宜家酒店");
    }
}

旅行:

public class Travel {

    private Ticket ticket;
    private Hotel hotel;
    private Car car;

    public Travel() {
        ticket = new Ticket();
        hotel = new Hotel();
        car = new Car();
    }

    public void getTicket(String day){
        ticket.getTicket(day);
    }

    public void getHotel(){
        hotel.getHotel();
    }

    public void getCar(){
        car.getCar();
    }

}

测试:

#享元模式(Flyweight Pattern) Use sharing to support large numbers of fine-grained objects efficiently.

 减少创建对象的数量

  四个角色:

    抽象享元(Flyweight)角色:抽象接口

    具体享元(ConcreteFlyweight)角色:实现享元接口的具体的可共享对象

    享元工厂(FlyweightFactory)角色:池容器:保证享元对象可以被系统适当的共享

    客户端(Client)角色:存储享元对象

 例子:棋子

抽象享元:

public interface Flyweight {

    void put(int x,int y);

}

具体享元:

public class ConcreteFlyweight implements Flyweight{

    private String color;

    public ConcreteFlyweight(String color) {
        this.color = color;
    }

    public void put(int x, int y) {
        System.out.print("坐标:x:"+x+"; y:"+y+"; ");
        System.out.println("颜色:"+color);
    }

}

享元工厂:

public class FlyweightFactory {
    static final Flyweight WHITE = new ConcreteFlyweight("白色");
    static final Flyweight BLACK = new ConcreteFlyweight("黑色");
    public static Flyweight getFlyweight(String color){
        if(color.equals("白色")){
            return WHITE;
        }else if(color.equals("黑色")){
            return BLACK;
        }
        return null;
    }
}

测试:

 

 

 总结:

 代理模式:通过代理访问对象

 装饰模式:动态添加功能

 适配器模式:让两个独立的类一起工作

 组合模式:对象组合成树形结构

 桥梁模式:抽象与实现解耦,使得二者可以独立变化

 外观模式:通过统一的接口访问子系统

 享元模式:池;共享对象可有效地支持大量的细粒度的对象

 

 @

posted @ 2020-04-28 16:44  DarGi  阅读(217)  评论(0)    收藏  举报