3.设计模式之后七种模式桥接装饰者组合外观享元代理模板

这篇具有很好参考价值的文章主要介绍了3.设计模式之后七种模式桥接装饰者组合外观享元代理模板。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.桥接模式 bridge(抽象类的实现的子类,通过聚合间接调用接口方法 就是桥)

  1. 实现和抽象分开,使他可以独立改变
  2. 结构型设计模式
  3. 基于类的最小设计原则(增加功能,增加最少个数的类),通过封装 聚合和继承让不同类实现不同职责
    图 23桥接模式原理图
    3.设计模式之后七种模式桥接装饰者组合外观享元代理模板,设计模式,设计模式

图 26桥接模式传统解决手机操作问题
3.设计模式之后七种模式桥接装饰者组合外观享元代理模板,设计模式,设计模式

图 24桥接模式解决手机操作问题
3.设计模式之后七种模式桥接装饰者组合外观享元代理模板,设计模式,设计模式

图 27桥接模式代码结构
3.设计模式之后七种模式桥接装饰者组合外观享元代理模板,设计模式,设计模式

--------传统方式实现,需要先实现后继承------

public interface Phone {
    void open();
    void call();
    void close();
}

public class Folded implements Phone {

    @Override
    public void open() {
        System.out.println("折叠手机开机");
    }

    @Override
    public void call() {
        System.out.println("折叠手机打电话");
    }

    @Override
    public void close() {
        System.out.println("折叠手机关机");

    }
}
public class VIVOFold extends Folded {

    public void open() {
        super.open();
        System.out.println("VIVO手机开机");
    }


    public void call() {
        super.call();
        System.out.println("VIVO手机打电话");
    }


    public void close() {
        super.close();
        System.out.println("VIVO手机关机");
    }
}
public class XIAOMIFold extends Folded {
    @Override
    public void open() {
        super.open();
        System.out.println("小米手机开机");
    }

    @Override
    public void call() {
        super.call();
        System.out.println("小米手机打电话");
    }

    @Override
    public void close() {
        super.close();
        System.out.println("小米手机关机");
    }
}

public class UpRight implements Phone {
    @Override
    public void open() {
        System.out.println("直立手机开机");
    }

    @Override
    public void call() {
        System.out.println("直立手机打电话");
    }

    @Override
    public void close() {
        System.out.println("直立手机关机");

    }
}
public class VIVOUpRight extends UpRight {

    public void open() {
        super.open();
        System.out.println("VIVO手机开机");
    }


    public void call() {
        super.call();
        System.out.println("VIVO手机打电话");
    }


    public void close() {
        super.close();
        System.out.println("VIVO手机关机");
    }
}
public class XIAOMIUpRight extends UpRight {
    @Override
    public void open() {
        super.open();
        System.out.println("小米手机开机");
    }

    @Override
    public void call() {
        super.call();
        System.out.println("小米手机打电话");
    }

    @Override
    public void close() {
        super.close();
        System.out.println("小米手机关机");
    }
}
//测试类
public class Client {
    public static void main(String[] args) {
        Phone phone=new VIVOFold();
        phone.open();
        phone.call();;
        phone.close();
        System.out.println("--------------");
        Phone phone1=new XIAOMIFold();
        phone1.open();
        phone1.call();;
        phone1.close();
        System.out.println("--------------");
        Phone phone2=new XIAOMIUpRight();
        phone2.open();
        phone2.call();;
        phone2.close();
    }
}


---改进的代码----------
   //1. 写桥接接口 子类实现接口
public interface BrandBridge {
    void open();
    void call();
    void close();
}
public class Vivo implements BrandBridge {
    @Override
    public void open() {
        System.out.println("vivo打开手机");
    }

    @Override
    public void call() {
        System.out.println("vivo打电话");
    }

    @Override
    public void close() {
        System.out.println("vivo关闭手机");

    }
}
public class XiaoMi implements BrandBridge {
    @Override
    public void open() {
        System.out.println("xiaomi打开手机");
    }

    @Override
    public void call() {
        System.out.println("xiaomi打电话");
    }

    @Override
    public void close() {
        System.out.println("xiaomi关闭手机");

    }
}


    //2.再写手机类, 聚合桥接类,写继承的手机子类
       public class Phone {
    BrandBridge brand;
    Phone(BrandBridge brand){
        this.brand=brand;
    }
    void open(){
        brand.open();
    }
    void call(){
        brand.call();
    }
    void close(){
        brand.close();
    }


}
  public class FoldedPhone extends Phone {
    public FoldedPhone(BrandBridge brand) {
        super(brand);
    }
    public void open(){
        System.out.println("折叠手机");
        super.open();
    }
    public void call(){
        System.out.println("折叠手机");
        super.call();
    }
    public void close(){
        System.out.println("折叠手机");
        super.close();
    }


}
//设计模式好不好用主要看客户端调用方便
public class Client {
    public static void main(String[] args) {
        FoldedPhone foldedPhone = new FoldedPhone(new Vivo());
        foldedPhone.open();
        foldedPhone.call();
        foldedPhone.close();
        System.out.println("====================");
        UpRightPhone upRightPhone = new UpRightPhone(new XiaoMi());
        upRightPhone.open();
        upRightPhone.call();
        upRightPhone.close();


    }
}

//总结: 如果我想一个类拓展性好, 那我先写桥接接口 再子类实现
//然后写个这个类聚合,然后子类调用桥接类方法,
//一句话: 逆序写代码…

2.桥接模式在JDBC的应用(与标准的有出入)
图 25桥接模式在JDBC源码分析 DriverManager是桥接类(不变的部分),(增加的部分是) ConnectionImpl …Oracle…
3.设计模式之后七种模式桥接装饰者组合外观享元代理模板,设计模式,设计模式

  1.调用了getConnection方法返回Connection对象
 Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jams", "root", "root");
  //源代码 getConnection()方法
  @CallerSensitive
public static Connection getConnection(String url,
    String user, String password) throws SQLException {
    java.util.Properties info = new java.util.Properties();

    if (user != null) {
        info.put("user", user);
    }
    if (password != null) {
        info.put("password", password);
    }

    return (getConnection(url, info, Reflection.getCallerClass()));
}

//往里面找

 //  Worker method called by the public getConnection() methods.
    private static Connection getConnection(
        String url, java.util.Properties info, Class<?> caller) throws SQLException {
     
        ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
        synchronized(DriverManager.class) {
            // synchronize loading of the correct classloader.
            if (callerCL == null) {
                callerCL = Thread.currentThread().getContextClassLoader();
            }
        }

        if(url == null) {
            throw new SQLException("The url cannot be null", "08001");
        }

        println("DriverManager.getConnection(\"" + url + "\")");

        // Walk through the loaded registeredDrivers attempting to make a connection.
        // Remember the first exception that gets raised so we can reraise it.
        SQLException reason = null;

        for(DriverInfo aDriver : registeredDrivers) { //我认为这里可能使用了桥接模式,寻找对应的驱动,找到mysql驱动返回
            // If the caller does not have permission to load the driver then
            // skip it.
            if(isDriverAllowed(aDriver.driver, callerCL)) {
                try {
                    println("    trying " + aDriver.driver.getClass().getName());
                    Connection con = aDriver.driver.connect(url, info);  //这里调用了Driver类实际上调用了DriverManager的 DriverManager.registerDriver(new Driver());,桥接了DriverManager
             //他的这个聚合直接使用静态类实现....
                    if (con != null) {
                        // Success!  
                        println("getConnection returning " + aDriver.driver.getClass().getName());
                        return (con);  
                    }
                } catch (SQLException ex) {
                    if (reason == null) {
                        reason = ex;
                    }
                }

            } else {
                println("    skipping: " + aDriver.getClass().getName());
            }

        }

        // if we got here nobody could connect.
        if (reason != null)    {
            println("getConnection failed: " + reason);
            throw reason;
        }

        println("getConnection: no suitable driver found for "+ url);
        throw new SQLException("No suitable driver found for "+ url, "08001");
    }
   //aDriver.driver.connect(url, info); 方法有DriverManager
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    public Driver() throws SQLException {
    }

    static {
        try {
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }
}
//public class NonRegisteringDriver implements Driver的类中
    public Connection connect(String url, Properties info) throws SQLException {
        if (url != null) {
            if (StringUtils.startsWithIgnoreCase(url, "jdbc:mysql:loadbalance://")) {
                return this.connectLoadBalanced(url, info);
            }

            if (StringUtils.startsWithIgnoreCase(url, "jdbc:mysql:replication://")) {
                return this.connectReplicationConnection(url, info);
            }
        }

        Properties props = null;
        if ((props = this.parseURL(url, info)) == null) {
            return null;
        } else {
            try {
                com.mysql.jdbc.Connection newConn = ConnectionImpl.getInstance(this.host(props), this.port(props), props, this.database(props), url); //ConnectionImpl其实是Mysql连接的类,没有注册过类,则默认注册mysql
                return newConn;
            } catch (SQLException var6) {
                throw var6;
            } catch (Exception var7) {
                SQLException sqlEx = SQLError.createSQLException(Messages.getString("NonRegisteringDriver.17") + var7.toString() + Messages.getString("NonRegisteringDriver.18"), "08001");
                sqlEx.initCause(var7);
                throw sqlEx;
            }
        }
    }

//总结: 1.如何学会看源代码 ,先看类的头部关系画uml类图(一个一个点进去,逐步画类 然后找类和类的关系),然后debug调试运行过程

3.优缺点

  1. 提高系统灵活性.帮助系统分层设计
  2. 桥接替代多层继承,可以减少类爆炸问题,减低系统维护成本
  3. 增加系统理解难度
  4. 要正确区分系统独立变化的2个维度(抽象和实现)

4.应用场景(一句话,代码需要增加分类功能 可以采用聚合调用聚合的方法)

  1. jdbc驱动
  2. 银行转账 普通用户(抽象 不变) 和网上转账(实现 后期增加的)
  3. 消息分类 消息类型:即时消息和延时消息(抽象) 消息分类: 数据短信 QQ消息(实现)

5.装饰者模式(工作常用)

图28装饰者模式原理图
3.设计模式之后七种模式桥接装饰者组合外观享元代理模板,设计模式,设计模式

图31装饰者模式星巴克咖啡传统
3.设计模式之后七种模式桥接装饰者组合外观享元代理模板,设计模式,设计模式

  1. 星巴克咖啡订单问题(计算不同搭配的钱/单品咖啡)导致类爆炸(排列组合实现cost方法)
  2. 改进为装饰者(使用非常方便,并且只加一个类就可以与其他类组合) 满足ocp原则
    图 29装饰者模式星巴克咖啡改进
    3.设计模式之后七种模式桥接装饰者组合外观享元代理模板,设计模式,设计模式
                   Drink coffee=new Coffee(); 
                        coffee.cost();//计算多少钱
                   Drink add=new Chocolate(coffee);
                      add.cost(); //计算咖啡和巧克力的全部费用
                      
              像打包一个快递 :主体(Component)  衣服 陶瓷 被装饰者
                                        包装(Decorator) 泡沫 木板    装饰者(递归加上价格)

-----全部代码-------
//全部方法和成员由父类创建 继承给子类调用

//1.创建抽象类

public abstract class Drink {
    private String desciption;
    private float price;

    public String getDesciption() {
        return desciption;
    }

    public void setDesciption(String desciption) {
        this.desciption = desciption;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }
}
//2.继承抽象类
public  class Coffee extends Drink{
}
//3.创建子类
public class Decaf extends Coffee {
    public Decaf(){
        setDesciption("Decaf");
        setPrice(9.0f);
    }
}
public class ShortBlack extends Coffee {
    ShortBlack(){
        setDesciption("ShortBlack");
        setPrice(10.0f);
    }
}
//4.创建装饰者类 继承和组合 被装饰者类  !!!
public  class Decorator extends Drink {
    Drink obj;
    Decorator(Drink obj){
        this.obj=obj;
    }


}
//5.创建装饰者的子类
public class Chocolate extends Decorator{
    public Chocolate(Drink obj) {
        super(obj);
        setDesciption(obj.getDesciption()+"巧克力");
        setPrice(obj.getPrice()+3.0f);
    }
}
public class Milk extends Decorator{
    Milk(Drink obj) {
        super(obj);
        setDesciption(obj.getDesciption()+"牛奶");
        setPrice(obj.getPrice()+2.0f);
    }
}

//测试类

public class Client {
    public static void main(String[] args) {
        Drink decaf = new Decaf();
        Drink chocolate = new Chocolate(decaf);
        Drink chocolate1 = new Chocolate(chocolate);
        float cost = chocolate1.getPrice();
        System.out.println(cost); //会得到全部加入购物车饮料的总钱数
        System.out.println(chocolate1.getDesciption());


    }
}

6.装饰者在JDK IO流的应用 InputStream(被装饰者)的FilterInputStream相当于(装饰者),下面的DataInputStream也继承
30装饰者模式jdkio源码原理图
3.设计模式之后七种模式桥接装饰者组合外观享元代理模板,设计模式,设计模式

//核心代码装饰者类继承和组合父类
public
class FilterInputStream extends InputStream { //继承父类 和 DataInputStream同级
    /**
     * The input stream to be filtered.
     */
    protected volatile InputStream in; //装饰父类 构造方法也是传入这个
//测试代码,子类的子类可以把父类组合到类内,这样的形式可能是装饰者模式
      DataInputStream dis = new DataInputStream(new FileInputStream("d:\\1.txt")); 
        DataInputStream dis1 = new DataInputStream(dis);
        //之前我就好奇为什么要把自己作为参数传给自己,原来是使用了装饰者
        System.out.println(dis1.read());
        dis.close();

7.组合模式(部分整体模式) 解决继承难以管理,树型结构组合对象,需要对象间有共同的功能
图组合32 33
3.设计模式之后七种模式桥接装饰者组合外观享元代理模板,设计模式,设计模式
3.设计模式之后七种模式桥接装饰者组合外观享元代理模板,设计模式,设计模式

3.设计模式之后七种模式桥接装饰者组合外观享元代理模板,设计模式,设计模式

1.几个概念
所有 整体和部分类继承 component(可以是接口/抽象类)然后实现他的 add() remove() print()方法空实现,方便管理,leaf是实现基础的get set方法

//传统的学校院系问题 学校 继承 学院 继承 院系 方便管理
----所有代码-----
//先写一个抽象类或接口,定义好整颗树,通用的方法

public abstract class Component {
    private String name; // 名字
    private String des; // 说明
    Component(String name,String des){

        this.name = name;
        this.des = des;
    }

    void add(Component component){
        throw new UnsupportedOperationException();
    };
    void remove(Component component){
        throw new UnsupportedOperationException();
    }
    void print(){
        throw new UnsupportedOperationException();
    }

    public String getName() {
        return name;
    }

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

    public String getDes() {
        return des;
    }

    public void setDes(String des) {
        this.des = des;
    }
}

//每一层的树都继承 组件,使用list存放他的孩子

public class University extends Component{

    List<Component> components=new ArrayList<Component>();
    University(String name, String des) {
        super(name, des);
    }
    void add(Component component){
        components.add(component);
    };
    void remove(Component component){
        components.remove(component);
    }
    void print(){

        System.out.println("--------------" + getName() + "--------------");
        for (Component component : components) {
            component.print();
        }
    }
}
public class College extends Component {

    List<Component> components=new ArrayList<Component>();
    College(String name, String res) {
        super(name, res);
    }
    void add(Component component){
        components.add(component);
    };
    void remove(Component component){
        components.remove(component);
    }
    void print(){
        System.out.println("--------------" + getName() +"--------------");
        for (Component component : components) {
            component.print();
        }
    }
}

//最后一层叶子不放东西,所以不用list存放数据

public class Department extends Component {
    Department(String name,String res) {
        super(name, res);
    }

    void print(){
        System.out.println(getName()+getDes() );
    }
    public String getName() {
        return super.getName();
    }

    public String getDes() {
        return super.getDes();
    }


}

//这才是设计模式的精髓,直接让代码富有逻辑性,可读性增强,写新代码也容易

public class Client {
    public static void main(String[] args) {
        University university = new University("清华大学","中国一流大学");
        College college = new College("计算机学院", "计算机学院很好");
        college.add(new Department("计算机科学与技术", "王牌专业"));
        college.add(new Department("软件工程", "也是王牌专业"));
        university.add(college);

        College college1 = new College("财经学院", "财经很好");
        college1.add(new Department("会计专业","都是金融人才"));
        college1.add(new Department("金融工程专业","都是金融人才1"));
        university.add(college1);
        university.print();

    }
}
//输出结果(非常简单)
--------------清华大学--------------
--------------计算机学院--------------
计算机科学与技术王牌专业
软件工程也是王牌专业
--------------财经学院--------------
会计专业都是金融人才
金融工程专业都是金融人才1

//删除一个专业,可以自己定义删除的代码细节

public class Client {
    public static void main(String[] args) {
        University university = new University("清华大学","中国一流大学");
        College college = new College("计算机学院", "计算机学院很好");
        Department department = new Department("计算机科学与技术", "王牌专业");
        college.add(department);
        college.add(new Department("软件工程", "也是王牌专业"));
        college.remove(department);
        university.add(college);

        College college1 = new College("财经学院", "财经很好");
        college1.add(new Department("会计专业","都是金融人才"));
        college1.add(new Department("金融工程专业","都是金融人才1"));
        university.add(college1);
        university.print();

    }
}

8.组合模式在HashMap的应用
Map是component HashMap是composite 有put putall方法
Node是hashMap的静态内部类(叶子节点的),实现Map 相当于 Leaf没有put putall方法
全部都实现了Map所以map是component
3.设计模式之后七种模式桥接装饰者组合外观享元代理模板,设计模式,设计模式
9.外观(界面)(过程facade)模式,就是封装类的思想,加一层类 来屏蔽子系统的调用 和简单工厂越看越像不同的是工厂是创建类的,而外观是调用不同功能的

外观类: 知道哪些子系统负责什么,给调用端的请求到子系统
子系统: 处理外观类给的任务,功能的实际提供者

  1. 传统方式实现影院系统 直接Client调用各个子系统 如图: 35外观模式解决传统问题
  2. 外观模式实现 创建影院设备类, (通过构造方法饿汉式初始化,分成多个阶段的方法调用的类) client调用外观类 如图 36外观模式

3.设计模式之后七种模式桥接装饰者组合外观享元代理模板,设计模式,设计模式
3.设计模式之后七种模式桥接装饰者组合外观享元代理模板,设计模式,设计模式

//客户端调用

public class Client {
    public static void main(String[] args) {
        Facade facade = new Facade();
        facade.ready();
        System.out.println("----------");
        facade.stop();
    }
}
//外观类 核心类
public class Facade {
    private  DVD dvd;
    private  Projector projector;
    private  Screen screen;
    private  Stere stere;
    private Lighting lighting;
    Facade(){
        dvd=DVD.getInstance();
        projector=Projector.getInstance();
        screen=Screen.getInstance();
        stere=Stere.getInstance();
        lighting=Lighting.getInstance();
    }

    public void ready(){
        screen.open();
        lighting.stop();
        projector.open();
        stere.open();
        dvd.play();
    }

    public void stop(){
        dvd.stop();
        stere.stop();
        projector.close();
        lighting.open();
        screen.close();

    }



}



//下面是子系统类
public class DVD {
    private static DVD instance=new DVD();

    public static DVD getInstance() {
        return instance;
    }
    public  void play(){
        System.out.println("开启播放dvd");
    }
    public  void stop(){
        System.out.println("关闭dvd");
    }
}
public class Lighting {
    private static Lighting instance=new Lighting();

    public static Lighting getInstance() {
        return instance;
    }
    public  void open(){
        System.out.println("开灯");
    }
    public  void stop(){
        System.out.println("关灯");
    }
}
public class Projector {
    private static Projector instance=new Projector();

    public static Projector getInstance() {
        return instance;
    }
    public  void open(){
        System.out.println("开启投影仪");
    }
    public  void close(){
        System.out.println("关闭投影仪");
    }
    
    
}
public class Screen {
    private static Screen instance=new Screen();

    public static Screen getInstance() {
        return instance;
    }
    public  void open(){
        System.out.println("打开幕布");
    }
    public  void close(){
        System.out.println("关闭幕布");
    }


}
public class Stere {
    private static Stere instance=new Stere();

    public static Stere getInstance() {
        return instance;
    }
    public  void open(){
        System.out.println("开启立体声");
    }
    public  void stop(){
        System.out.println("关闭立体声");
    }
}

10.外观模式在mybatis的应用
图 37.外观模式mybastis源码分析Configuration(外观类)的newMetaObject()方法
Configuration是外观类,子系统是DefaultObjectFactory DefaultObjectWrapperFactory DefaultReflectorFactory

3.设计模式之后七种模式桥接装饰者组合外观享元代理模板,设计模式,设计模式

import org.apache.ibatis.session.Configuration;
  public MetaObject newMetaObject(Object object) {
    return MetaObject.forObject(object, objectFactory, objectWrapperFactory);
  }
  public static MetaObject forObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory) {
    if (object == null) {
      return SystemMetaObject.NULL_META_OBJECT;
    } else {
      return new MetaObject(object, objectFactory, objectWrapperFactory);
    }
  }

//到MetaObject类

  private MetaObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory) {
    this.originalObject = object;
    this.objectFactory = objectFactory;
    this.objectWrapperFactory = objectWrapperFactory;

    if (object instanceof ObjectWrapper) {
      this.objectWrapper = (ObjectWrapper) object;
    } else if (objectWrapperFactory.hasWrapperFor(object)) {
      this.objectWrapper = objectWrapperFactory.getWrapperFor(this, object);
    } else if (object instanceof Map) {
      this.objectWrapper = new MapWrapper(this, (Map) object);
    } else if (object instanceof Collection) {
      this.objectWrapper = new CollectionWrapper(this, (Collection) object);
    } else {
      this.objectWrapper = new BeanWrapper(this, object);
    }
  }

11.外观模式的注意事项

  1. 降低客户端访问子系统复杂性(解耦)
  2. 用于系统太过复杂需要分层的时候
  3. 子系统太少了,不如直接使用,不用外观模式
  4. 维护遗留大项目 可以使用外观模式

12.享元(蝇量 flyweight)(共享对象)模式(开发用得多 string和池技术) 需求相似度高不要copy

  1. 解决的问题 38享元模式原理图
    1. 避免重复对象内存浪费的问题,但是提供系统复杂度 s1=“aaa” 和new String(“aaa”);指向常量池的同一个位置
    2. 解决网站外包复用问题,传统方案是复制粘贴定制修改
  2. 4个角色
    1. FlyWeight 抽象的享元角色,定义了对象的内部和外部状态的接口/实现
    2. ConcreteFlyWeight 具体的享元角色,返回共享对象
    3. UnSharedConcreteFlyWeight 不可共享的享元角色,一般不会出现在享元工厂里
    4. FlyWeightFactory 享元工厂类,得到对象的方法 用集合HashMap/HashTable存放共享的对象,
    3.内部和外部状态 (内部放在集合,外部构造器传进来)
    内部: 不随环境改变的状态(对象内) 5子棋 棋的颜色
    外部: 随环境改变的 5子棋 位置
    3.设计模式之后七种模式桥接装饰者组合外观享元代理模板,设计模式,设计模式

----解决外包问题完整代码------

//抽象类
public abstract class WebSite {

    abstract void  use(User user);
}
//创建类
public class ConcreteWebSite extends WebSite {
    String type=""; //内部状态
    ConcreteWebSite(String type) {
        this.type=type;
    }

    @Override
    void use(User user) { //外部状态
        System.out.println("网站类型为"+type+"正在被"+user.getName()+"使用");
    }
}
//外部状态类
public class User {
    private String name;
    User(String name){
        this.name=name;
    }

    public String getName() {
        return name;
    }

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

//享元工厂类!!!,共享数据类
public class WebSiteFactory {
    HashMap<String, ConcreteWebSite> pool=new HashMap<>();
    public WebSite getWebSiteCategory(String type){
        if(!pool.containsKey(type)){
            pool.put(type,new ConcreteWebSite(type));
        }
        return (WebSite)pool.get(type);

    }
    int getCount(){
        return pool.size();
    }
}

//客户端调用测试发现有缓存的效果
//其实强智系统也可能使用了享元模式,一个强智系统由多个大学使用

public class Client {
    public static void main(String[] args) {
        WebSiteFactory webSiteFactory = new WebSiteFactory();
        WebSite blog = webSiteFactory.getWebSiteCategory("博客"); //设置内部状态为博客(由我决定) 
        blog.use(new User("小明"));  //外部状态为小明(由客户决定)
        WebSite blog1 = webSiteFactory.getWebSiteCategory("博客");
        blog1.use(new User("小叶"));
        WebSite webSite = webSiteFactory.getWebSiteCategory("房地产");
        webSite.use(new User("小李子"));
        System.out.println(webSiteFactory.getCount());
    }
}

//输出
网站类型为博客正在被小明使用
网站类型为博客正在被小叶使用
网站类型为房地产正在被小李子使用
2 //创建了2个网站,博客和房地产,重复创建的会直接返回

13.jdk里面Integer使用了享元模式

   x=Integer.valueOf(127);//  x==y  -128到127使用享元模式,返回相同的对象,比new要快
   y=Integer.valueOf(127);
public static Integer valueOf(int i) { //外部状态
    if (i >= IntegerCache.low && i <= IntegerCache.high)  //-128 到127  内部状态
        return IntegerCache.cache[i + (-IntegerCache.low)];   //数组也是个集合 static final Integer cache[];  
    return new Integer(i);
}

14.代理(proxy)模式(替你做事,增强你的能力) 给对象(类)创建替身增强功能

  1. 解决的问题
    1.动态增加对象的功能
    2. 缺点 代理对象和被代理对象需要实现相同的接口,导致创建大量的代理对象,不好维护
  2. 代理的对象可以是远程对象,创建开销大的对象,需要安全控制的对象
  3. 代理的分类
    1.静态代理 需要类实现接口和聚合,有个代理类和被代理类
    3.设计模式之后七种模式桥接装饰者组合外观享元代理模板,设计模式,设计模式
public interface Play {
    void play();
}
//被代理类
public class PlayImpl implements Play{

    @Override
    public void play() {
        System.out.println("被代理类的方法");
    }
}
//代理类
public class PlayPoxy implements Play{
    Play play;
    public PlayPoxy(Play play){
        this.play=play;
    }

    @Override
    public void play() {
        System.out.println("代理前");
        play.play();
        System.out.println("代理后");

    }
}
public class Client {
    public static void main(String[] args) {
        PlayPoxy playPoxy = new PlayPoxy(new PlayImpl());
        playPoxy.play();
    }
}

2.动态代理(JDK代理) 使用jdk的方法, 传入一个接口 写个工厂

Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),new InvocationHandler(){ invoke方法的 returnVal=method.invoke(target,args); return returnVal;//可以没有,观察一下args})输出对象hashcode带有 $proxy说明是代理对象

public interface Play {
    void play();
}
public class PlayImpl implements Play {

    @Override
    public void play() {
        System.out.println("被代理类的方法");
    }
}
public class PlayPoxy {
    Object target;

    public PlayPoxy(Object target) {
        this.target=target;
    }

    public Object getProxyInstance(){

         return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {    //代理全部方法调用可用method的方法判断调用哪个方法
                System.out.println("jdk动态代理前");
                Object invoke = method.invoke(target, args);
                System.out.println("jdk动态代理后");
                return invoke;
            }
        });
    }

}
public class Client {
    public static void main(String[] args) {
        Play target = new PlayImpl();
        PlayPoxy playPoxy = new PlayPoxy(target);
        Play proxyInstance = (Play)playPoxy.getProxyInstance();
        proxyInstance.play();
    }
}             

3.Cglib动态代理 在内存创建单个对象,不需要实现接口和聚合 spring AOP的底层
//导入cglib的jar文件 ,代理类实现 MethodIntercepttor类的方法 intercept和jdk代理写法一样
3.设计模式之后七种模式桥接装饰者组合外观享元代理模板,设计模式,设计模式

  1. 不能为final/static会报错,不会拦截和执行业务方法
public class PlayImpl  {


    public int play() {
        System.out.printl![请添加图片描述](https://img-blog.csdnimg.cn/a085daacf6a04548b588d5456fcdbe2a.png)
n("被代理类的方法"); return 1;
    }
}
public class PlayPoxy implements MethodInterceptor {
    private Object target;
    PlayPoxy(Object target){
        this.target = target;
    }
    //设置返回的代理对象方法
    public Object getProxyInstance() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();

    }
    //具体处理增强功能的方法
    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("Cglib代理模式 ~~ 开始");
        Object returnVal = method.invoke(target, args);
        System.out.println("Cglib代理模式 ~~ 提交");
        return returnVal;  //依赖函数的返回值也可以修改
    }
}
public class Client {
    public static void main(String[] args) {

        PlayPoxy playPoxy = new PlayPoxy(new PlayImpl());
        PlayImpl proxyInstance = (PlayImpl) playPoxy.getProxyInstance();
        proxyInstance.play();
    }
}

4.其他代理
防火墙代理:(内网穿透服务器对公网的访问)
缓存代理: 请求文件先到缓存取,如果没有就到数据库或公网取
远程代理: 本地的对象代理远程的对象像本地访问一样访问资源
同步代理: 代理需要多线程同步的对象(加上同步代码块)

1

5.模板(template method)模式

  1. 是什么?
    1.是行为型模式
    2.几个类的几个方法是一样的,部分不一样,有一个final方法写调用处理流程
    3.缺点是每个不同实现需要子类实现,类爆炸
  //抽象类写一个final方法以免被子类覆盖
   //改进加入构子方法直接返回状态,如果模板方法判断是否加另外的东西,不用改模板,可以让子类覆盖达到灵活控制的效果
  //覆盖,增加灵活性(实现其他功能)
public abstract class SoyMilk {
    
    final void  make(){
        select();
        if(customWantAdditions()==true){
            add();
        }
        soap();
        beat();
     };
    void  select(){
        System.out.println("挑选大豆");
    };
    abstract void  add();
    void  soap(){
        System.out.println("吸水");
    };
    void  beat(){
        System.out.println("打碎");
    };

    //构子增加拓展性
    boolean customWantAdditions(){
       return true;
    }
}

//写他的子类
public class RedSoyMilk extends SoyMilk {
    @Override
    void add() {
        System.out.println("添加红豆");
    }
}
public class GreenSoyBean extends SoyMilk {
    @Override
    void add() {
        System.out.println("加绿豆");
    }
}
public class PureSoyMilk extends SoyMilk {
    @Override
    void add() {
    }
    @Override
     boolean customWantAdditions(){
        return false;
    }
}
//测试
public class Client {
    public static void main(String[] args) {
        SoyMilk redSoyMilk = new RedSoyMilk();
        redSoyMilk.make();
        System.out.println("--------------");
        SoyMilk greenSoyBean = new GreenSoyBean();
        greenSoyBean.make();
        System.out.println("制作纯豆奶");

        SoyMilk pureSoyMilk = new PureSoyMilk();
        pureSoyMilk.make();
    }
}

//运行结果

挑选大豆
添加红豆
吸水
打碎
--------------
挑选大豆
加绿豆
吸水
打碎
制作纯豆奶
挑选大豆
吸水
打碎

16.模板方法在spring是应用
//抽象类定义模板方法的实现过程
//上面的类又有继承 ,到ClassPathXmlApplicationContext我们就可以直接使用了因为一层一层方法继承下来,所有功能完成了实现
3.设计模式之后七种模式桥接装饰者组合外观享元代理模板,设计模式,设计模式

public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {
    String CONFIG_LOCATION_DELIMITERS = ",; \t\n";
    String CONVERSION_SERVICE_BEAN_NAME = "conversionService";
    String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";
    String ENVIRONMENT_BEAN_NAME = "environment";
    String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties";
    String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";

    void setId(String var1);

    void setParent(ApplicationContext var1);

    ConfigurableEnvironment getEnvironment();

    void setEnvironment(ConfigurableEnvironment var1);

    void addBeanFactoryPostProcessor(BeanFactoryPostProcessor var1);

    void addApplicationListener(ApplicationListener<?> var1);

    void refresh() throws BeansException, IllegalStateException;

    void registerShutdownHook();

    void close();

    boolean isActive();

    ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
}

//AbstractApplicationContext的refresh相当于make文章来源地址https://www.toymoban.com/news/detail-520462.html

 public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext, DisposableBean //继承和实现确定处理过程
    public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);
	//处理的过程 只是这里依赖外部依赖(组合进来)
            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var5) {
                this.destroyBeans();
                this.cancelRefresh(var5);
                throw var5;
            }

        }
    }
  //空实现
  //onfreash是构子
  protected void onRefresh() throws BeansException {
    }
  //GenericApplicationContext类覆盖了父类的方法(子类覆盖父类具体实现方法,但没有全部实现的流程)

    protected final void refreshBeanFactory() throws IllegalStateException {
        if (this.refreshed) {
            throw new IllegalStateException("GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
        } else {
            this.beanFactory.setSerializationId(this.getId());
            this.refreshed = true;
        }
    }

到了这里,关于3.设计模式之后七种模式桥接装饰者组合外观享元代理模板的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 设计模式深度解析:AI如何影响装饰器模式与组合模式的选择与应用

    ​🌈 个人主页: danci_ 🔥 系列专栏: 《设计模式》《MYSQL应用》 💪🏻 制定明确可量化的目标,坚持默默的做事。 AI如何影响装饰器模式与组合模式的选择与应用       在今天这个快速发展的技术时代,人工智能(AI)正以前所未有的速度影响着软件开发的各个方面。设

    2024年04月16日
    浏览(21)
  • 4.设计模式之后七种模式后11种模式命令访问者迭代器发布订阅中介者忘备录解释器状态策略职责链和空模式

    1.命令(command)模式 不知道命令接收者(对象)是谁,支持撤销 (接受者 间接调用执行 的具体行为) 命令调用者和接收者解耦 //只要实现命令接口即可 (就是客户端给个命令,然后命令类传给接收类执行) 优点和缺点 容易撤销操作 命令队列可以多线程操作 增加过多的命令类 空命令也

    2024年02月12日
    浏览(40)
  • 二十四种设计模式与六大设计原则(三):【装饰模式、迭代器模式、组合模式、观察者模式、责任链模式、访问者模式】的定义、举例说明、核心思想、适用场景和优缺点

    接上次博客:二十四种设计模式与六大设计原则(二):【门面模式、适配器模式、模板方法模式、建造者模式、桥梁模式、命令模式】的定义、举例说明、核心思想、适用场景和优缺点-CSDN博客 目录 装饰模式【Decorator Pattern】 定义 举例说明 核心思想 适用场景 优缺点 迭代

    2024年04月17日
    浏览(43)
  • 七种常用的设计模式

    常用的七种设计模式:单例模式、工厂方法模式、抽象工厂模式、代理模式、装饰器模式、观察者模式和责任链模式。 设计模式分类 设计模式根据工作的目的,分为创建型模式、结构型模式和行为型模式三类。 创建型模式: 单例模式 、 工厂方法模式 、 抽象工厂模式 、创

    2024年02月01日
    浏览(25)
  • Java七种常用设计模式

    单例模式是(Singleton Pattern)Java中最常用的设计模式之一,它保证一个类仅有一个实例,并提供一个全局访问点。 实现单例模式的核心是将类的构造方法私有化,以防止外部直接通过构造函数创建实例。同时,类内部需要提供一个静态方法或变量来获取该类的唯一实例。 以

    2024年02月11日
    浏览(31)
  • 设计模式--装饰者模式

    (1) 可乐种类/单品可乐 :BaiShiCola(百事可乐) FeiChangCola(非常可乐) CoCola(可口可乐) (2) 调料/附品: Milk  Chocolate (3) 要求在扩展新的可乐种类时 要具有良好的扩展性 改动方便 维护方便 (4) 使用OO的来就算不同之类可乐的费用 客户可以点单品可乐 也可以单品可乐+调料组合 方案1 

    2024年02月02日
    浏览(30)
  • 设计模式——装饰者模式

    更多内容,前往 IT-BLOG 现实生活中常常需要给某类产品动态增加新的功能,如:给面条各种调味品。在软件开发过程中,有时想用一些现存的组件。这些组件可能只是完成一些核心功能。但在不改变其架构的情况下,可以动态地扩展其功能。所以这些都可以采用装饰模式来实

    2024年02月22日
    浏览(25)
  • 设计模式-装饰器模式

    装饰者模式的定义为:动态的给一个对象添加其它功能。 从扩展性来说,这种方式比继承更有弹性,更加灵活,装饰者模式也体现了开闭原则(OCP)。 星巴克咖啡订单项目(咖啡馆) : 1)咖啡种类/单品咖啡: Espresso(意大利浓咖啡)、ShortBlack、Decaf(无因咖啡)、LongBlack(美式咖啡) 2)

    2024年02月06日
    浏览(31)
  • 设计模式——装饰器模式

    装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。 装饰器模式通过将对象包装在装饰器类中,以便动态地修改其行为。 这种模式创建了一个装饰类,用来包装原有的

    2024年02月10日
    浏览(30)
  • 【设计模式】-装饰器模式

    在软件开发中,经常有需求对已有的对象进行功能的扩展,但是传统的继承方式会导致类的数量快速增多,且难以维护。为了解决这个问题,装饰器模式应运而生。 装饰器模式是一种结构型设计模式,它可以在运行时动态地将新的行为附加到对象上,而不改变其结构。这种方

    2024年02月14日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包