07. 适配器模式

image

Target:目标抽象类,此处是接口,客户需要用的特定接口;
Adapter:适配器类,关联适配者类,实现目标抽象类接口;
Adaptee:适配者类,被适配的角色,与Target不兼容的类,这个类需要适配(一般指三方类库)。
  适配者模式就是把一个类的接口(Adaptee)变换成客户端所期待的另一种接口(Target),从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作(Adapter)。

  • 模式优点:
    • 将目标类和适配者类解耦;
    • 增加了类的透明性和复用性,将具体的实现封装在适配者类中,对于客户端类来说是透明的,而且提高了适配者的复用性;
    • 灵活性和扩展性比较好。
  • 模式缺点:
    • 类适配器缺点:
    • 一次最多只能适配一个适配者类,不能同时适配多个适配者;
    • 适配者类不能为最终类;
    • 目标抽象类只能为接口,不能为类;
  • 对象适配器缺点:
    • 在适配器中置换适配者类的某些方法比较麻烦。

代码实现:

public class Client {
    public static void main(String[] args) {
        Target target = new Adapter();
        target.request(); // adaptee正在执行...
    }
}

interface Target {
    void request();
}

class Adaptee {
    public void specificRequest() {
        System.out.println("adaptee正在执行...");
    }
}

class Adapter extends Adaptee implements Target {
    @Override
    public void request() {
        specificRequest(); // adaptee类的方法
    }
}

(1)适配器模式例题

  使用Java语言实现一个双向适配器实例,使得猫可以学狗叫,狗可以学猫抓老鼠,绘制相应类图并使用代码编程模拟。

image

代码实现:

public class Client {
    public static void main(String[] args) {
        Cat cat = new Adapter();
        cat.miao(); // 猫在学狗在汪...

        Dog dog = new Adapter();
        dog.action(); // 狗在学猫在抓老鼠...
    }
}

interface Cat {
    void miao();
    void catchMouse();
}

interface Dog {
    void wang();
    void action();
}

class RealCat implements Cat {

    @Override
    public void miao() {
        System.out.println("猫在喵...");
    }

    @Override
    public void catchMouse() {
        System.out.println("猫在抓老鼠...");
    }
}

class RealDog implements Dog {

    @Override
    public void wang() {
        System.out.println("狗在汪...");
    }

    @Override
    public void action() {
        System.out.println("狗在跑...");
    }
}

class Adapter implements Dog, Cat {

    private Dog dog = new RealDog();
    private Cat cat = new RealCat();

    @Override
    public void miao() {
        System.out.print("猫在学");
        dog.wang();
    }

    @Override
    public void action() {
        System.out.print("狗在学");
        cat.catchMouse();
    }

    @Override
    public void catchMouse() {
    }

    @Override
    public void wang() {
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }
}

08. 桥接模式

image

Abstraction类:抽象类
Implementor接口:实现类接口
RefinedAbstraction类:扩充抽象类
ConcreteImplementorA类:具体实现类A
ConcreteImplementorB类:具体实现类B
  可以把抽象类和实现类接口当成两个维度,把两个维度联合起来就是将其中一个维度的类作为一个主类(Abstraction),然后把另一个维度当做属性(Implementor)。如笔,可分为颜色、笔类型两个维度来桥接,形成黑色毛笔、白色画笔等。

  • 模式优点:
    • 分离抽象接口及其实现部分;
    • 可以取代多层继承方案,极大地减少了子类的个数;
    • 提高了系统的可扩展性,在两个变化维度中任意扩展一个维度,不需要修改原有系统,符合开闭原则。
  • 模式缺点:
    • 会增加系统的理解与设计难度,由于关联关系建立在抽象层,要求开发者一开始就要针对抽象层进行设计与编程;
    • 正确识别出系统中两个独立变化的维度并不是一件容易的事情。

代码实现:

public class Client {
    public static void main(String[] args) {
        Abstraction abstraction = new RefinedAbstraction();
        // 调用第一个实现类
        abstraction.setImplementor(new ConcreteImplementorA());
        abstraction.operation();  // A执行...
        // 调用第二个实现类
        abstraction.setImplementor(new ConcreteImplementorB());
        abstraction.operation(); // B执行...
    }
}

abstract class Abstraction {
    Implementor implementor;
    
    public void setImplementor(Implementor implementor) {
        this.implementor = implementor;
    }
    
    public abstract void operation();
}

class RefinedAbstraction extends Abstraction {
    @Override
    public void operation() {
        implementor.operationImpl();
    }
}

interface Implementor {
    void operationImpl();
}

class ConcreteImplementorA implements Implementor {
    @Override
    public void operationImpl() {
        System.out.println("A执行...");
    }
}

class ConcreteImplementorB implements Implementor {
    @Override
    public void operationImpl() {
        System.out.println("B执行...");
    }
}

09. 组合模式

Component:抽象构件类,既可以代表叶子又可以代表容器,是组合中对象声明接口,在适当情况下,实现所有类共有的接口默认行为,用户访问和管理Component子部件,Component可以是抽象类或者接口;
Leaf:叶子构件,在组合中表示叶子节点,叶子节点没有子节点;
Composite:容器构件,非叶子节点,用于存储子部件,在Component接口中实现子部件的相关操作,比如增删查改。
Client:客户类。
  组合模式适用于具有树形结构的对象,如组织机构、文件目录等。组合模式有透明组合模式和安全组合模式。上图是透明组合模式,抽象构件声明了所有子类中的全部方法,所以客户端无须区别树叶对象和树枝对象,对客户端来说是透明的。但其缺点是:树叶构件本来没有 add()、remove() 及 getChild() 方法,却要实现它们(空实现或抛异常),这样会带来一些安全性问题。
代码实现:

public class Client {
    public static void main(String[] args) {
        Component root = new Composite();
        Component children1 = new Composite();
        Component children2 = new Composite();
        Component leaf1 = new Leaf("leaf1");
        Component leaf2 = new Leaf("leaf2");
        root.add(children1);
        root.add(children2);
        children1.add(leaf1);
        children2.add(leaf2);
        root.operation();
    }
}

// 抽象构件
abstract class Component {
    abstract void operation();
    abstract void add(Component c);
    abstract void remove(Component c);
    abstract Component getChild(int i);
}

// 叶子构件
class Leaf extends Component {
    private String leafName;
    public Leaf(String leafName) {
        this.leafName = leafName;
    }
    @Override
    void operation() {
        System.out.println(leafName);
    }
    @Override
    void add(Component c) {
        // 空实现
    }
    @Override
    void remove(Component c) {
        // 空实现
    }
    @Override
    Component getChild(int i) {
        return null;
    }
}

// 容器构件
class Composite extends Component {
    private List<Component> children = new ArrayList();
    @Override
    void operation() {
        for (Component component : children) {
            // 若非叶子节点,递归执行
            component.operation();
        }
    }
    @Override
    void add(Component c) {
        children.add(c);
    }
    @Override
    void remove(Component c) {
        children.remove(c);
    }
    @Override
    Component getChild(int i) {
        return children.get(i);
    }
}

(1)组合模式例题

  在该教育机构的OA系统中可以给各级办公室下发公文,现采用组合模式设计该机构的结构,绘制相应的类图并编程模拟实现。在客户类中模拟下发公文。

Organization类:抽象部件类,其中只定义了叶子构件(Office)和容器构件(Department)的共有方法,即接收公文的方法;
Office类:叶子构件,叶子结点,表示教务/行政办公室,有接收公文的方法;
Department类:容器构件,非叶子部件,用于存储子部件,有增加子部件、删除子部件、发送公文、接收公文等操作。
Client类:客户类。
以上是安全组合模式。
代码实现:

public class Client {
    public static void main(String[] args) {
        Department beijing = new Department("北京总部");
        Office office1 = new Office("教务办公室1");
        Office office01 = new Office("行政办公室1");
        Department hunan = new Department("湖南分校");
        Office office2 = new Office("教务办公室2");
        Office office02 = new Office("行政办公室2");
        Department changsha = new Department("长沙教学点");
        Department yueyang = new Department("岳阳教学点");
        Office office3 = new Office("教务办公室3");
        Office office03 = new Office("行政办公室3");
        Office office4 = new Office("教务办公室4");
        Office office04 = new Office("行政办公室4");

        beijing.add(office1);
        beijing.add(hunan);
        beijing.add(office01);

        hunan.add(office2);
        hunan.add(changsha);
        hunan.add(yueyang);
        hunan.add(office02);

        changsha.add(office3);
        changsha.add(office03);

        yueyang.add(office4);
        yueyang.add(office04);

        beijing.sendMessage();
        System.out.println("------------------------------------------------------------------");
        hunan.sendMessage();
    }
}

// 抽象构件
interface Organization {
    void receiveMessage();
}

// 叶子构件
class Office implements Organization {
    private String name;

    public Office(String name) {
        this.name = name;
    }

    @Override
    public void receiveMessage() {
        System.out.println(name + "接收到公文");
    }

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

    public String getName() {
        return this.name;
    }
}

// 容器构件
class Department implements Organization {
    private String name;
    private List<Organization> children = new ArrayList<>();

    public Department(String name) {
        this.name = name;
    }

    @Override
    public void receiveMessage() {
        System.out.println(name + "接收到公文");
    }

    public void sendMessage() {
        for (Organization child : children) {
            if (child instanceof Office) {
                System.out.println(name + "给" + ((Office) child).getName() + "下发文件");
                child.receiveMessage();
            } else if (child instanceof Department) {
                System.out.println(name + "给" + ((Department) child).getName() + "下发文件");
                child.receiveMessage();
                ((Department) child).sendMessage();
            }
        }
    }

    public void add(Organization o) {
        children.add(o);
    }

    public void remove(Organization o) {
        children.remove(o);
    }

    public Organization getChild(int i) {
        return children.get(i);
    }

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

    public String getName() {
        return this.name;
    }
}

10. 装饰模式

Component类:抽象构件,给出一个抽象类(或接口),以规范准备接收附加责任或附加功能的对象
ConcreteComponent类:具体构件,定义一个将要接收附加责任或附加功能的对象
Decorator:抽象装饰类:持有一个构件(Component)对象的实例,并有一个与抽象构件一致的方法
ConcreteDecorator类:具体装饰类,负责给构件对象添加对应的新功能
  装饰者模式是动态地给一个对象添加一些额外的职责(功能),同时又不改变其结构。可以用来扩展一个类的功能,动态增加功能,动态撤销。

public class Client {
    public static void main(String[] args) {
        Component tea = new ConcreteComponent(); // 奶茶
        tea.operation(); // 一杯奶茶
        System.out.println();
        tea = new ConcreteDecoratorA(tea); // 加糖
        tea.operation(); // 一杯奶茶 + 一勺糖
        System.out.println();
        tea = new ConcreteDecoratorB(tea); // 加冰
        tea.operation(); // 一杯奶茶 + 一勺糖 + 一块冰
        System.out.println();
        tea = new ConcreteDecoratorA(tea); // 再加糖
        tea.operation(); // 一杯奶茶 + 一勺糖 + 一块冰 + 一勺糖
    }
}

// 抽象构件接口
interface Component {
    void operation();
}

// 具体构件
class ConcreteComponent implements Component {

    @Override
    public void operation() {
        System.out.print("一杯奶茶");
    }
}

// 抽象装饰类
abstract class Decorator implements Component {

    private Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void operation() {
        component.operation();
    }
}

// 具体装饰类A
class ConcreteDecoratorA extends Decorator {

    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        super.operation();
        addBehavior();
    }

    private void addBehavior() {
        System.out.print(" + 一勺糖");
    }

}

// 具体装饰类B
class ConcreteDecoratorB extends Decorator {

    public ConcreteDecoratorB(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        super.operation();
        addBehavior();
    }

    private void addBehavior() {
        System.out.print(" + 一块冰");
    }
}

原文地址:http://www.cnblogs.com/hbjiaxin/p/16907552.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性