zoukankan      html  css  js  c++  java
  • 设计模式三:适配器,桥接,组合,装饰,外观,享元,代理

    复习一下,之前说的都是创建型模式

    有工厂三家族,简单工厂,工厂方法,抽象工厂

    简单工厂是一个作坊里产一款产品

    工厂方法是一个大作坊有几个小作坊,每个小作坊产一款产品

    抽象工厂是一个大作坊有几个小作坊,每个小作坊产不同系列的一部分。最后产一系列的产品

    建造者是老板管搞论文的和搞工程的,搞工程的就是几个架构搭建,搞论文的就是搞些公式和结果图搞,最后来到实验室找到老板就知道实验室有什么东西了

    享元是简历复制。把要改的改了。争取共享一些东西。

    单例就是一个家庭只能生一个孩子。没有的时候创建一个,有了的话,你来我家查孩子,就带你找那个独苗。数据库里面建立连接,就是这种模式的体现。

    以上粗俗的话主要为了方便理解和回忆,请勿当真。。。。

    推荐一下个人GitHub,里面有设计模式的源码  https://github.com/tori22/DesignPattern

    (竟然是HTTPS协议的)

    今天学习结构型模式

    一.适配器

    将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于

    接口不兼容而不能一起工作的那些类可以一起工作。

    优点:

    通过适配器,客户端可以调用同一接口,因而对客户端来说是透明的。这样做更简单、更直接、更紧凑。

    复用了现存的类,解决了现存类和复用环境要求不一致的问题。

    将目标类和适配者类解耦,通过引入一个适配器类重用现有的适配者类,而无需修改原有代码。

    一个对象适配器可以把多个不同的适配者类适配到同一个目标,也就是说,

    同一个适配器可以把适配者类和它的子类都适配到目标接口。

    缺点:

    对于对象适配器来说,更换适配器的实现过程比较复杂。

    适用场景:

    系统需要使用现有的类,而这些类的接口不符合系统的接口。

    想要建立一个可以重用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。

    两个类所做的事情相同或相似,但是具有不同接口的时候。

    旧的系统开发的类已经实现了一些功能,但是客户端却只能以另外接口的形式访问,

    但我们不希望手动更改原有类的时候。

    使用第三方组件,组件接口定义和自己定义的不同,不希望修改自己的接口,但是要使用第三方组件接口的功能。

    package AdapterPattern;
    
    public class Adaptee {
    
        public void specificRequest() {
            System.out.println("特殊请求!");
        }
    }
    package AdapterPattern;
    
    public class Adapter extends Target {
        private Adaptee adaptee = new Adaptee();
    
        @Override
        public void request() {
            adaptee.specificRequest();
        }
    }
    package AdapterPattern;
    
    public class Client {
        public static void main(String[] args) {
            Target target = new Adapter();
            target.request();
        }
    }
    package AdapterPattern;
    
    public class Target {
        public void request() {
            System.out.println("普通请求");
        }
    }

    二.桥接

    将抽象不笨与它的实现部分分离,使它们都可以独立地变化.

    桥接模式的使用场景:

    1、当一个对象有多个变化因素的时候,通过抽象这些变化因素,将依赖具体实现,修改为依赖抽象。

    2、当某个变化因素在多个对象中共享时。我们可以抽象出这个变化因素,然后实现这些不同的变化因素。

    3、当我们期望一个对象的多个变化因素可以动态的变化,而且不影响客户的程序的使用时。

    8.组合(合成):

    将对象组合成树形结构以表示‘部分-整体’的层次结构,组合模式使得用户

    对单个对象和组合对象的使用具有一致性。

    使用场景:

    当发现需求中是体现部分与整体层次结构时,以及你希望用户可以忽略组合对象与单个对象的不同,

    统一地使用组合结构中的所有对象时,就应该考虑组合模式了。

    package BridgePattern;
    
    public class Abstraction {
        protected Implementor mImplementor;
    
        public void setImplementor(Implementor implementor) {
            mImplementor = implementor;
        }
        public void operation() {
            mImplementor.operation();
        }
    }
    package BridgePattern;
    
    public class Client {
    
        public static void main(String[] args) {
            Abstraction ab = new RefinedAbstraction();
    
            ab.setImplementor(new ConcrateImplementorA());
            ab.operation();
    
            ab.setImplementor(new ConcrateImplementorB());
            ab.operation();
        }
    }
    package BridgePattern;
    
    public class ConcrateImplementorA extends Implementor {
        @Override
        public void operation() {
            System.out.println("具体实现A的方法执行");
        }
    }
    package BridgePattern;
    
    public class ConcrateImplementorB extends Implementor {
        @Override
        public void operation() {
            System.out.println("具体实现B的方法执行");
        }
    }
    package BridgePattern;
    
    public abstract class Implementor {
        public abstract void operation();
    }
    package BridgePattern;
    
    public class RefinedAbstraction extends Abstraction {
        @Override
        public void operation() {
            mImplementor.operation();
        }
    }

    三.组合

    package CompositePattern;
    
    public class Client {
    
        public static void main(String[] args) {
            Composite root = new Composite("root");
            root.add(new Leaf("Leaf A"));
            root.add(new Leaf("Leaf B"));
    
            Composite comp = new Composite("Composite X");
            comp.add(new Leaf("Leaf XA"));
            comp.add(new Leaf("Leaf XB"));
    
            root.add(comp);
    
            Composite comp2 = new Composite("Composite XY");
            comp2.add(new Leaf("Leaf XYA"));
            comp2.add(new Leaf("Leaf XYB"));
            comp.add(comp2);
    
            root.add(new Leaf("Leaf C"));
            Leaf leaf = new Leaf("Leaf D");
            root.add(leaf);
            root.remove(leaf);
    
            root.display(1);
    
        }
    }
    package CompositePattern;
    
    
    
    public abstract class Component {
    
        protected String mName;
    
        public Component(String name) {
            mName = name;
        }
    
        public abstract void add(Component c);
        public abstract void remove(Component c);
        public abstract void display(int depth);
    }
    package CompositePattern;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Composite extends Component {
    
        private List<Component> childern = new ArrayList<>();
    
        public Composite(String name) {
            super(name);
        }
        @Override
        public void add(Component c) {
            childern.add(c);
        }
    
        @Override
        public void remove(Component c) {
            childern.remove(c);
        }
    
        @Override
        public void display(int depth) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < depth ; i++) {
                sb.append("-");
            }
            System.out.println(sb.append(mName).toString());
    
            for (Component c:childern) {
                c.display(depth+2);
            }
        }
    }
    package CompositePattern;
    
    public class Leaf extends Component{
    
        public Leaf(String name) {
            super(name);
        }
        @Override
        public void add(Component c) {
            System.out.println("cannot add to a leaf");
        }
    
        @Override
        public void remove(Component c) {
            System.out.println("cannot remove to a leaf");
        }
    
        @Override
        public void display(int depth) {
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < depth ; i++) {
                stringBuilder.append("-");
            }
    
            System.out.println(stringBuilder.append(mName).toString());
        }
    }

    四.装饰

    动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更加灵活。

    1.在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。

    2 处理那些可以撤消的职责。

    3.当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,

    为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。

    另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

    package DecoratorPattern;
    
    public abstract class Component {
        public abstract void Opeartion();
    }
    package DecoratorPattern;
    
    public class ConcreateComponent extends Component {
        @Override
        public void Opeartion() {
            System.out.println("具体对象的操作");
        }
    }
    package DecoratorPattern;
    
    public class ConcreateDecoratorA extends Decorator{
        public String addedState;
    
        @Override
        public void Opeartion() {
            super.Opeartion();
            addedState = "New State";
            System.out.println("具体装饰对象A的操作" + addedState);
        }
    }
    package DecoratorPattern;
    
    public class ConcreateDecoratorB extends Decorator{
    
    
        @Override
        public void Opeartion() {
            super.Opeartion();
            addedBehavior();
            System.out.println("具体装饰对象B" );
        }
    
        private void addedBehavior() {
    
        }
    }
    package DecoratorPattern;
    
    public abstract class Decorator extends Component {
    
        protected Component mcomponent;
    
        public void setcomponent(Component component) {
            mcomponent = component;
        }
        @Override
        public void Opeartion() {
            if (mcomponent != null) {
                mcomponent.Opeartion();
            }
        }
    }
    package DecoratorPattern;
    
    public class Test {
        public static void main(String[] args) {
            ConcreateComponent component = new ConcreateComponent();
            ConcreateDecoratorA decoratorA = new ConcreateDecoratorA();
            ConcreateDecoratorB decoratorB = new ConcreateDecoratorB();
    
            decoratorA.setcomponent(component);
            decoratorB.setcomponent(decoratorA);
            decoratorB.Opeartion();
        }
    }

    五.外观

    为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,

    这个接口使得这一子系统更加容易使用。

    适用环境:

    在开发阶段,子系统往往因为不断的重构演化而变得越来越复杂,

    增加外观Facade可以提供一个简单的接口,减少它们之间的依赖.

    在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,可以为

    新系统开发一个外观Facade类,来提供设计粗糙或高度复杂的遗留代码的比较清晰

    简单的接口,让新系统与Facade对象交互,Facade与遗留代码交互所有复杂的工作。

    优点:

    实现了子系统与客户端之间的松耦合关系。

    客户端屏蔽了子系统组件,减少了客户端所需处理的对象数目,并使得子系统使用起来更加容易

    package FacedePattern;
    
    public class Client {
    
        public static void main(String[] args) {
            Facede facede = new Facede();
    
            facede.methodA();
            facede.methodB();
        }
    }
    package FacedePattern;
    
    public class Facede {
        private SubSystemOne one;
        private SubSystemTwo two;
        private SubSystemThree three;
        private SubSystemFour four;
    
        public Facede() {
            one = new SubSystemOne();
            two = new SubSystemTwo();
            three = new SubSystemThree();
            four = new SubSystemFour();
        }
    
        public void methodA() {
            System.out.println("方法组A------");
            one.methodOne();
            two.methodTwo();
            four.methodFour();
        }
    
        public void methodB() {
            System.out.println("方法组B----------");
            two.methodTwo();
            three.methodThree();
        }
    
    }
    package FacedePattern;
    
    public class SubSystemFour {
        public void methodFour() {
            System.out.println("子系统方法四");
        }
    }
    package FacedePattern;
    
    public class SubSystemOne {
        public void methodOne() {
            System.out.println("子系统方法一");
        }
    }
    package FacedePattern;
    
    public class SubSystemThree {
        public void methodThree() {
            System.out.println("子系统方法三");
        }
    }
    package FacedePattern;
    
    public class SubSystemTwo {
        public void methodTwo() {
            System.out.println("子系统方法二");
        }
    }

    六.享元

    为运用共享技术有效地支持大量细粒度的对象。

    优点:

    1、享元模式的优点在于它能够极大的减少系统中对象的个数。

    2、享元模式由于使用了外部状态,外部状态相对独立,不会影响到内部状态,

    所以享元模式使得享元对象能够在不同的环境被共享。

    缺点

    1、由于享元模式需要区分外部状态和内部状态,使得应用程序在某种程度上来说更加复杂化了。

    2、为了使对象可以共享,享元模式需要将享元对象的状态外部化,而读取外部状态使得运行时间变长。

    模式适用场景

    1、如果一个系统中存在大量的相同或者相似的对象,由于这类对象的大量使用,会造成系统内存的耗费,

    可以使用享元模式来减少系统中对象的数量。

    2、对象的大部分状态都可以外部化,可以将这些外部状态传入对象中。

    package FlyweightPattern;
    
    public class Client {
    
        public static void main(String[] args) {
            int extrinsicstate = 22;
    
            FlyweightFactory factory = new FlyweightFactory();
    
            Flyweight fx = factory.getFlyweight("x");
            fx.operation(--extrinsicstate);
    
            Flyweight fy = factory.getFlyweight("y");
            fy.operation(--extrinsicstate);
    
            Flyweight fz = factory.getFlyweight("z");
            fz.operation(--extrinsicstate);
    
            Flyweight uf = new UnsharedConcreteFlyweight();
            uf.operation(--extrinsicstate);
        }
    }
    package FlyweightPattern;
    
    public class ConcreteFlyweight extends Flyweight{
        @Override
        public void operation(int extrinsicstate) {
            System.out.println(String.format("具体Flyweight:%s",extrinsicstate));
        }
    }
    package FlyweightPattern;
    
    public abstract class Flyweight {
        public abstract void operation(int extrinsicstate);
    }
    package FlyweightPattern;
    
    import java.util.Hashtable;
    
    public class FlyweightFactory {
    
        private Hashtable flyweight = new Hashtable();
    
        public FlyweightFactory() {
            flyweight.put("x",new ConcreteFlyweight());
            flyweight.put("y",new ConcreteFlyweight());
            flyweight.put("z",new ConcreteFlyweight());
        }
    
        public Flyweight getFlyweight(String key) {
            return (Flyweight)flyweight.get(key);
        }
    }
    package FlyweightPattern;
    
    public class UnsharedConcreteFlyweight extends Flyweight {
        @Override
        public void operation(int extrinsicstate) {
            System.out.println(String.format("不共享的具体Flyweight:%d",extrinsicstate));
        }
    }

    七.代理

    为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用

    另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

    代理模式常被分为远程代理、虚拟代理、保护代理等等。

    优点:

    1)代理模式能将代理对象与真正被调用的对象分离,在一定程度上降低了系统的耦合度。

    2)代理模式在客户端和目标对象之间起到一个中介作用,这样可以起到保护目标对象的作用。

    代理对象也可以对目标对象调用之前进行其他操作。

    缺点:

    1)在客户端和目标对象增加一个代理对象,会造成请求处理速度变慢。

    2)增加了系统的复杂度。

    使用场景:

    1)远程代理,也就是为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于

    不同地址空间的事实。

    2)虚拟代理,根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的对象。

    3)安全代理,用来控制真实对象访问时的权限。

    4)智能指引,当调用目标对象时,代理可以处理其他的一些操作。

    package ProxyPattern;
    
    public class Client {
        public static void main(String[] args) {
            Proxy proxy = new Proxy();
            proxy.request();
        }
    }
    package ProxyPattern;
    
    public class Proxy extends Subject {
       private RealSubject mRealSubject;
        @Override
        public void request() {
            if (mRealSubject == null) {
                mRealSubject = new RealSubject();
            }
    
            mRealSubject.request();
        }
    }
    package ProxyPattern;
    
    public class RealSubject extends Subject {
        @Override
        public void request() {
            System.out.println("真实请求");
        }
    }
    package ProxyPattern;
    
    public abstract class Subject {
        public abstract void request();
    }
  • 相关阅读:
    SpringCloud之架构搭建
    3.通用权限设计——SnailAspNetCoreFramework快速开发框架之后端设计
    2.接口输入校验、输出格式、及异常处理——SnailAspNetCoreFramework快速开发框架之后端设计
    1、框架内各项目及目录的介绍和总设计思路——SnailAspNetCoreFramework快速开发框架
    SnailAspNetCoreFramework框架系列博客
    Asp.net core中间件实现原理及用法解说
    深入剖析linq的联接
    webapi框架搭建系列博客
    webapi框架搭建-依赖注入之autofac
    webapi框架搭建-创建项目(三)-webapi owin
  • 原文地址:https://www.cnblogs.com/xiaoyingying/p/8810856.html
Copyright © 2011-2022 走看看