23种设计模式(二)

本文详细解读了七种结构型设计模式:适配器模式用于兼容不同接口,装饰者模式动态扩展功能,代理模式中介隔离,外观模式简化接口,桥接模式解耦结构,组合模式表示层次关系,享元模式优化内存使用。通过实例演示了每种模式的应用和优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

适配器 Adapter

适配器模式(Adapter Pattern)将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。

public class Adaptee {
    public void request() {
        System.out.println("连接。。。");
        System.out.println("end。。。");
    }
}
public class Computer {
    public void net(NetUsb nt){
        System.out.println("开机");
        nt.handleRequest();
    }
}

public interface NetUsb {
    public void handleRequest();
}
//适配器
public class Adapter  implements NetUsb{
    private Adaptee adaptee;
    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }
    @Override
    public void handleRequest() {
        adaptee.request();
    }
}

 public static void main(String[] args) {
        Computer computer = new Computer();
        Adaptee adaptee = new Adaptee();

        Adapter adapter = new Adapter(adaptee);

        computer.net(adapter);
    }

装饰者 Decorator

动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性。

//抽象构件
public abstract class Snack {
    public String des;//描述
    private float price = 0.0f; //单价

    public String getDes() {
        return des;
    }

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

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }
    //计算费用 方法
    public abstract float costs();
}

//手抓饼 基础构件
public class ShreddedCake extends Snack{
    public ShreddedCake(){
        setPrice(5.0f);
        setDes("ShreddedCake :" + costs());
    }
    @Override
    public float costs() {
        return super.getPrice();
    }
}
//烤冷面 基础构件
public class GrilledColdNoodles extends Snack{
    public GrilledColdNoodles(){
        setPrice(5.0f);
        setDes("GrilledColdNoodles : " + costs() );
    }

    @Override
    public float costs() {
        return super.getPrice();
    }
}
//装饰
public class Decorator extends Snack{
    private Snack s;

    public Decorator(Snack s) {
        this.s = s;
    }

    @Override
    public float costs() {
        return super.getPrice()+s.costs();
    }

    @Override
    public String getDes() {
        //输出装饰者的信息
        return des + " " +  getPrice() + "+" + s.getDes();
    }
}
//具体装饰角色
public class ChineseLeaf extends Decorator{
    public ChineseLeaf(Snack s) {
        super(s);
        setDes("Chinese leaf ");
        setPrice(1.0f);
    }
}
public class Sausage extends Decorator{
    public Sausage(Snack s) {
        super(s);
        setDes(" sausage");
        setPrice(1.5f);
    }
}
public class Egg extends Decorator{
    public Egg(Snack s) {
        super(s);
        setDes("Egg");
        setPrice(1.0f);
    }
}
//测试
  public static void main(String[] args) {
        Snack s1 = new GrilledColdNoodles();//烤冷面
        System.out.println(s1.costs()+ "\t" +"constitute(组成):" +s1.getDes());
        s1 = new Egg(s1);//加一个鸡蛋
        System.out.println(s1.costs()+ "\t" +"constitute(组成):" +s1.getDes());
        s1 = new ChineseLeaf(s1);//加肠
        System.out.println(s1.costs()+ "\t" +"constitute(组成):" +s1.getDes());
        System.out.println("==================================");
        Snack s2 = new ShreddedCake();//手抓饼
        System.out.println(s2.costs()+ "\t" +"constitute(组成):" +s2.getDes());
    }

代理Proxy

中介隔离作用:在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。

//静态代理
//创建服务接口
public interface BuyHouse {
    void buyHouse();
}
//实现接口
public class BuyHouseImpl implements BuyHouse{
    @Override
    public void buyHouse() {
        System.out.println("具体实现。。。。");
    }
}
//创建代理类
public class BuyHouseProxy implements BuyHouse{
    private BuyHouse bh;

    public BuyHouseProxy(BuyHouse bh) {
        this.bh = bh;
    }

    @Override
    public void buyHouse() {
        System.out.println("begin。。。。。");
        bh.buyHouse();
        System.out.println("end。。。。。");
    }
}
//静态代理
public class Main {
    public static void main(String[] args) {
        BuyHouseImpl b = new BuyHouseImpl();
        b.buyHouse();
        //生成代理对象
        BuyHouseProxy bhp = new BuyHouseProxy(b);
        bhp.buyHouse();
    }
}
//动态 代理  invoke
public class ProxyHandler implements InvocationHandler {
    private Object object;

    public ProxyHandler(Object object) {
        this.object = object;
    }

    @Override        //  被代理对象           方法          参数
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        befor();
        System.out.println(method.getName());
        Object o = method.invoke(object, args);
        after();
        return o;
    }

   public void befor() {
        System.out.println("begin........");
    }

    public void after() {
        System.out.println("end..........");
    }
}
//动态代理
public class Main {
    public static void main(String[] args) {
        BuyHouse bh = new BuyHouseImpl();
        BuyHouse proxy = (BuyHouse) Proxy.newProxyInstance(BuyHouse.class.getClassLoader()
                , new Class[]{BuyHouse.class}
                , new ProxyHandler(bh));
        proxy.buyHouse();
    }
}
//cglib
public class CglibProxy {
    private Object target;
    public Object getInstance(final Object target) {
        this.target = target;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }
    public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        befor();
        Object result = methodProxy.invoke(object, args);
        after();
        return result;
    }
    public void befor(){
        System.out.println("begin.......");
    }
    public void after(){
        System.out.println("end.......");
    }
}
public static void main(String[] args) {
        BuyHouse buyHouse = new BuyHouseImpl();
        CglibProxy cp = new CglibProxy();
        BuyHouseImpl bcp = (BuyHouseImpl) cp.getInstance(buyHouse);
        bcp.buyHouse();
    }

外观模式  Facade

定义: 隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口。

该模式就是把一些复杂的流程封装成一个接口供给外部用户更简单的使用。

//子系统A
public class SubSystemA {
    public void start(){
        System.out.println("SubSystemA.method.1...");
    }
    public void shotdown(){
        System.out.println("SubSystemA.method.2..");
    }
}
//子系统B
public class SubSystemB {
    public void start(){
        System.out.println("SubSystemB.method.1...");
    }
    public void shotdown(){
        System.out.println("SubSystemB.method.2...");
    }
}
==================================
    //门面 外观
public class Facade {
    SubSystemA ssa;
    SubSystemB ssb;

    public Facade() {
        ssa = new SubSystemA();
        ssb = new SubSystemB();
    }

    public void start(){
        System.out.println("begin.start.");
        this.ssa.start();
        this.ssb.start();
        System.out.println("end.start.");
    }
    public void down(){
        System.out.println("begin.down.");
        this.ssa.shotdown();
        this.ssb.shotdown();
        System.out.println("end.down.");
    }
}
=========================
       public static void main(String[] args) {
        Facade facade = new Facade();
        facade.start();
        facade.down();
    }

桥接模式 Bridge

将抽象部分与它的实现部分分离,使他们都可以独立地变化。聚合代替继承

//品牌
public interface Brand {
    void info();
}
public class Apple implements Brand {
    @Override
    public void info() {
        System.out.print("Apple");
    }
}
public class Lenovo implements Brand {
    @Override
    public void info() {
        System.out.print("Lenovo");
    }
}
  //抽象电脑类型
public abstract class Computer {
    protected Brand brand;

    public Computer(Brand brand) {
        this.brand = brand;
    }

    public void info() {
        brand.info();
    }
}
class  DeskType extends Computer{

    public DeskType(Brand brand) {
        super(brand);
    }
    @Override
    public void info() {
        brand.info();
        System.out.print("\t" +  "DeskType");
    }
}

class  Laptop extends Computer{

    public Laptop(Brand brand) {
        super(brand);
    }
    @Override
    public void info() {
        brand.info();
        System.out.print("\t" + "Laptop");
    }
}
 public static void main(String[] args) {
        Computer c = new DeskType(new Apple());
        c.info();
        System.out.println();
        Computer c2 = new Laptop(new Lenovo());
        c2.info();
    }

组合模式Compostie

将对象组合成树形结构以表示“部分-整体”的层次结构。

abstract class Node {
    abstract public void p();
}

class LeafNode extends Node {
    String content;
    public LeafNode(String content) {this.content = content;}

    @Override
    public void p() {
        System.out.println(content);
    }
}

class BranchNode extends Node {
    List<Node> nodes = new ArrayList<>();

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

    @Override
    public void p() {
        System.out.println(name);
    }

    public void add(Node n) {
        nodes.add(n);
    }
}


public class Main {
    public static void main(String[] args) {

        BranchNode root = new BranchNode("root");
        BranchNode chapter1 = new BranchNode("chapter1");
        BranchNode chapter2 = new BranchNode("chapter2");
        Node c1 = new LeafNode("c1");
        Node c2 = new LeafNode("c2");
        BranchNode b21 = new BranchNode("section2.1");
        Node c21 = new LeafNode("c21");
        Node c22 = new LeafNode("c22");

        root.add(chapter1);
        root.add(chapter2);
        chapter1.add(c1);
        chapter1.add(c2);
        chapter2.add(b21);
        b21.add(c21);
        b21.add(c22);

        tree(root, 0);
    }

    static void tree(Node b, int depth) {
        for(int i=0; i<depth; i++) System.out.print("->");
        b.p();

        if(b instanceof BranchNode) {
            for (Node n : ((BranchNode)b).nodes) {
                tree(n, depth + 1);
            }
        }
    }

享元Flyweight

在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。

//抽象享元
public interface Flyweight {
    // 显示票价 参数为列车类型
    public void showPrice(String type);
}
//具体享元类
public class ConcreteFlyweight implements Flyweight {
    String from;
    String to;

    public ConcreteFlyweight(String from, String to) {
        this.from = from;
        this.to = to;
    }

    @Override
    public void showPrice(String type) {
        if (type.equals("Gaotie")){
            System.out.println("从" + from + "到" + to + "的高铁票价为198");
        }else{
            System.out.println("从" + from + "到" + to + "的高铁票价为98");
        }
    }
}
//享元工厂类
public class FlyweightFactory {
    static Map<String, Flyweight> map = new HashMap<String, Flyweight>();

    public static Flyweight getFlyweight(String from, String to) {
        String k = from + to;
        if (map.containsKey(k)) {
            System.out.println("使用存在 containsKey 查询" + k);
            return map.get(k);
        }else {
            System.out.println("创建对象 查询 " + k);
            ConcreteFlyweight concreteFlyweight = new ConcreteFlyweight(from, to);
            map.put(k,concreteFlyweight);
            return concreteFlyweight;
        }
    }
}
=======
      public static void main(String[] args) {
        FlyweightFactory.getFlyweight("北京","上海").showPrice("Gaotie");
        FlyweightFactory.getFlyweight("北京","上海").showPrice("Dongche");
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值