头图

每天5分钟-结构型模式(二)

cutey_none

桥接模式

桥接模式的目标是将抽象与实现解耦,使得两者可以独立地变化。桥接模式通过在公共接口和实现中使用继承来达到目的。

比如手机可以有多个品牌,那么可以把手机抽象出来;每个手机可以有多种实现,比如颜色不同、尺寸不同、性能不同和系统不同等等。

Abstraction: 抽象类

Implementation: 抽象的实现类

Refined: 扩充的抽象类

Specific Implementation: 具体实现类。

桥接模式UML类图

桥接模式

Abstraction

public abstract class AbstractionPhone {
    Implementor implementor;

    public Implementor getImplementorAppearance() {
        return implementor;
    }

    public void setImplementorAppearance(Implementor implementor) {
        this.implementor = implementor;
    }

    public abstract void operation();
}

Refined

public class RefineAbstractionOnePlus extends AbstractionPhone {

    @Override
    public void operation() {
        System.out.println("一加手机");
        implementor.operation();
    }
}
public class RefinedAbstractionPhoneApple extends AbstractionPhone {


    @Override
    public void operation() {
        System.out.println("苹果手机");
        implementor.operation();
    }
}

Implementor

public abstract class Implementor {
    public abstract void operation();
}

Concrete Implementor

public class ConcreteImplementorColor extends Implementor {
    @Override
    public void operation() {
        System.out.println("手机有关颜色的实现");
    }
}
public class ConcreteImplementorSize extends Implementor {
    @Override
    public void operation() {
        System.out.println("有关手机尺寸大小的实现");
    }
}

Client

public class Client {
    public static void main(String[] args) {
        AbstractionPhone phone = new RefineAbstractionOnePlus();
        phone.setImplementorAppearance(new ConcreteImplementorColor());
        phone.operation();
        phone.setImplementorAppearance(new ConcreteImplementorSize());
        phone.operation();
    }
}

组合模式

组合模式顾名思义就是把一组对象组合成一个复杂的单一整体,比如把对象组合成树形或者图形结构。

最简单常见的就是公司里面的人员分布,所有的员工是很复杂很多的,但是从CEO到最底层的员工会形成一个树结构。

Component: 抽象结点

Leaf: 叶子结点

Composite: 复合节点,该结点包括复合结点的子节点或者叶子结点的子结点

组合模式UML类图

组合模式

Component

public abstract class ComponentEmployee {
    String name;      //名字
    String position;   //职位
    String salary;    //薪水

    //报告人员情况
    public void report() {
        String str =  "Employee{" +
                "name='" + name + '\'' +
                ", position='" + position + '\'' +
                ", salary='" + salary + '\'' +
                '}';

        System.out.println(str);
    }

    public ComponentEmployee(String name, String position, String salary) {
        this.name = name;
        this.position = position;
        this.salary = salary;
    }

    //招聘员工
    public abstract void addEmployee(ComponentEmployee componentEmployee);

    //解雇员工
    public abstract void deleteEmployee(ComponentEmployee componentEmployee);

}

Composite

public class CompositeLeader extends ComponentEmployee {
    
    //这里本来应该是private,然后外部通过get获取才合适,为了演示
    List<ComponentEmployee> subComponentEmployees;

    public CompositeLeader(String name, String position, String salary) {
        super(name, position, salary);
        //new一个下一层员工的List集合
        subComponentEmployees = new ArrayList<>();
    }

    @Override
    public void addEmployee(ComponentEmployee componentEmployee) {
        subComponentEmployees.add(componentEmployee);
    }

    @Override
    public void deleteEmployee(ComponentEmployee componentEmployee) {
        subComponentEmployees.remove(componentEmployee);
    }

    @Override
    public void report() {
        System.out.println("我的情况:");
        super.report();

        System.out.println("我手下员工的情况");

        for (ComponentEmployee e: subComponentEmployees) {
            e.report();
        }
    }
}

Leaf

public class LeafStaff extends ComponentEmployee {
    public LeafStaff(String name, String position, String salary) {
        super(name, position, salary);
    }

    //手底都没有员工,增加和删除操作就空实现,注意这里的空实现
    @Override
    public void addEmployee(ComponentEmployee componentEmployee) {

    }

    @Override
    public void deleteEmployee(ComponentEmployee componentEmployee) {

    }

    @Override
    public void report() {
        super.report();
    }
}

可以注意到叶子结点里面有两个是空实现(因为最底层的员工手下没有其它员工),这样是不太安全的做法。很简单,只要Component 中的两个抽象方法删掉即可,然后在Composite 里面是新增方法,而不是重写方法。

外观模式(门面模式)

门面模式的目的是为复杂的子系统提供单一的统一的接口,这样客户端只需要了解结果,不必了解各个子系统间是如何运作的。

比如甲方尽管给产品经理提需求,他只要成品,至于说公司的内部是如调配如何完成,客户一概不理也没必要知道。

Facade: 子系统接口

SubSystem: 子系统中定义的类

门面模式UML类图

门面模式

Facade

public class FacadeLeader {
    private SubSystemArt subSystemArt = new SubSystemArt();
    private SubSystemDevelopment subSystemDevelopment = new SubSystemDevelopment();
    private SubSystemOperations subSystemOperations = new SubSystemOperations();

    //暴露给外界的方法,外界不知道具体内部是谁来干,干什么
    public void needArt() {
        subSystemArt.art();
    }

    public void needDevelop() {
        subSystemDevelopment.develop();
    }

    public void needOperation() {
        subSystemOperations.operate();
    }

}

SubSystem

public class SubSystemArt {
    public void art() {
        System.out.println("美工部门正在画图");
    }
}
public class SubSystemDevelopment {
    public void develop() {
        System.out.println("开发部门正在开发");
    }
}
public class SubSystemOperations {
    public void operate() {
        System.out.println("运维部门正在测试!");
    }
}

Client

public class Client {

    public static void main(String[] args) {
        FacadeLeader facadeLeader = new FacadeLeader();
        System.out.println("我们需要这个需求");
        facadeLeader.needArt();
        facadeLeader.needDevelop();
        facadeLeader.needOperation();
    }
    
}

享元模式

享元模式,听起来很高大上,但是实际上就是共享对象的一种模式。目的是通过在相似对象间的共享状态来减少内存占用。

比如王者里面的小兵在一定时间内攻击、双抗,移动速度都是一定的,那么就是通过享元模式来减少对象的生成,从而使得内存消耗较少。而对于那些打完主宰后的兵,因为不是重复的,所以可以作为非共享的状态。

Flyweight: 抽象享元类

Concrete Flyweight: 与其同伴共享状态的享元对象

Unshared Concrete Flyweight: 不共享其状态的享元对象

Flyweight Factory: 享元工厂类

享元模式UML类图

享元模式

Flyweight

public abstract class FlyweightSoldier {
    public abstract void play();
}

Concrete Flyweight

public class ConcreteFlyweightNormalSoldier extends FlyweightSoldier {
    String type;

    public ConcreteFlyweightNormalSoldier(String type) {
        this.type = type;
    }

    @Override
    public void play() {
        System.out.println("生成小兵:" + type);
    }
}

Unshared Concrete Flyweight

public class UnsharedConcreteFlyweightGeneral extends FlyweightSoldier {
    @Override
    public void play() {
        System.out.println("根据不同情况生成的龙");
    }
}

Flyweight Factory

public class FlyweightFactory {
    private Hashtable<String, FlyweightSoldier> flyweights = new Hashtable<>();

    public ConcreteFlyweightNormalSoldier getSoldier(String key) {
        if (!flyweights.contains(key)) {
            flyweights.put(key, new ConcreteFlyweightNormalSoldier(key));
        }

        return (ConcreteFlyweightNormalSoldier) flyweights.get(key);
    }

    public UnsharedConcreteFlyweightGeneral getGeneral(String key) {
        flyweights.put(key, new UnsharedConcreteFlyweightGeneral());
        return (UnsharedConcreteFlyweightGeneral) flyweights.get(key);
    }
}

这里注意了,因为普通小兵是共享的,所以当有key的时候就不用再new一个小兵,直接返回即可;而对于特殊小兵来说,不管是否有key,都会new一个兵put进去。

Client

public class Client {
    public static void main(String[] args) {
        FlyweightFactory factory = new FlyweightFactory();

        for (int i = 0; i < 3; i++) {
            System.out.println("第" + i + 1 + "波兵线");
            factory.getSoldier("近战兵").play();
            factory.getSoldier("弓箭手").play();
            factory.getSoldier("法师兵").play();
        }
        //到这里其实只创建了三个对象

        for (int i = 0; i < 2; i++) {
            System.out.println("第" + i + "波特殊兵线");
            factory.getGeneral("减双抗龙").play();
            factory.getGeneral("减攻速龙").play();
        }
        //到这里创建了7个对象,3 + 4
    }
}

阅读 453
3 声望
0 粉丝
0 条评论
3 声望
0 粉丝
文章目录
宣传栏