23种设计模式中篇

结构型设计模式 ,共7种

(1)桥接模式

(2)装饰者模式

(3)组合模式

(4)适配器模式

(5)外观模式

(6)享元模式

(7)代理模式

桥接模式【jdbc采用的就是这种模式】

将抽象和实现部分的分离,更好的可扩展性,桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围有一定的局限性

//抽象的实现类
public interface Memory {

    void addMemory();
}

//具体的实现类
public class Memory6G  implements Memory{

    @Override
    public void addMemory() {
        System.out.println("安装了6G内存");
        
    }

}

//具体的实现类
public class Memory8G  implements Memory{

    @Override
    public void addMemory() {
        System.out.println("安装了8G内存");
    }

}

//具体部分的抽象
public abstract class Phone {
    
    protected  Memory memory;

    public void setMemory(Memory memory) {
        this.memory = memory;
    }
    
    protected abstract void buyPhone();
}

public class Huiwei extends Phone{

    
    @Override
    protected void buyPhone() {
        System.out.println("购买华为手机");
        memory.addMemory();
        
    }

}

public class Xiaomi extends  Phone {

    @Override
    protected void buyPhone() {
        System.out.println("购买小米手机");
        memory.addMemory();
    }

}

public class MainClass {

    public static void main(String[] args) {
        
        Phone  phone =   new Huiwei();
        phone.setMemory(new Memory6G());
        phone.buyPhone();
        System.out.println("===============");
        phone.setMemory(new Memory8G());
        phone.buyPhone();
        
    }
}

 

装饰者模式【jdk中有关流的操作】

给已经存在的对象动态的添加功能

//被装饰对象基类
public abstract class Girl {

    String description = "no particular";
 
    public String getDescription(){
        return description;
    }

}

//具体被装饰对象
public class AmericanGirl extends Girl {

    public AmericanGirl() {
        description = "American Girl";
    }

}

//装饰者抽象类
public abstract class GirlDecorator extends Girl {
 
    public abstract String getDescription();
 
}

//具体装饰者
public class Science extends GirlDecorator {

    private Girl girl;

    public Science(Girl girl) {
        this.girl = girl;
    }

    @Override
    public String getDescription() {
        return this.girl.getDescription() + "  Like Science";
    }

    public void caltulateStuff() {
        System.out.println("scientific calculation!");
    }
}

//具体装饰者
public class Art extends GirlDecorator {
 
    private Girl girl;
 
    public Art(Girl girl){
        this.girl = girl;
    }
 
    @Override
    public String getDescription() {
        return this.girl.getDescription() + "  Like Art";
    }
 
    public void draw() {
        System.out.println("draw pictures!");
    }
}

public class MainClass {
 
    public static void main(String[] args) {
        //普通美国女孩
        Girl g1 = new AmericanGirl();
        System.out.println(g1.getDescription());
        
        //喜欢科学
        Girl g2 = new Science(g1);
        System.out.println(g2.getDescription());
 
        //喜欢艺术
        Girl g3 = new Art(g2);
        System.out.println(g3.getDescription());
    }
}

 

组合模式

将对象组合成树形结构以表示“部分-整体”的层次结构。即对象包含对象,整体包含部分,组合模式使客户端可以使用一致的方法操作单个对象和组合对象

/**
 * 节点公共抽象类
 */
public abstract class Node {

    private String name;

    /**
     * 带参数的构造方法
     * @param name
     */
    public Node(String name){
        this.name = name;
    }

    /**
     * 获得节点信息
     * @return
     */
    public String getInfo(){
        return "名称:"+name;
    }
}

/**
 * 叶子节点(文件)
 */
public class File extends Node {
    
    /**
     * 调用父类的构造方法
     * @param name
     */
    public File(String name) {
        super(name);
    }
}

/**
 * 分支节点(文件夹)
 */
public class Folder extends Node{

    /**
     * 子集
     */
    private ArrayList children = new ArrayList();

    /**
     * 带参数的构造方法
     * @param name
     */
    public Folder(String name){
        super(name);
    }

    /**
     * 新增节点,有可能是文件也有可能是文件夹
     * @param node
     */
    public void add(Node node){
        this.children.add(node);
    }

    /**
     * 获得子集
     *
     * @return
     */
    public ArrayList getChildren() {
        return children;
    }
}

public class MainClass {

    public static void main(String[] args) {

        //定义根节点
        Folder root = new Folder("root");

        //定义二级节点的文件夹
        Folder imageFolder = new Folder("image-folder");
        Folder documentFolder = new Folder("document-folder");
        //定义二级节点的文件
        File systemFile = new File("system-file.bat");

        //定义三级节点的文件夹
        Folder pngFolder = new Folder("png-folder");
        Folder gifFolder = new Folder("gif-folder");
        //定义三级节点的文件
        File testHtml = new File("test.html");
        File testJS = new File("test.js");

        //填充一级文件夹
        root.add(imageFolder);
        root.add(documentFolder);
        root.add(systemFile);
        //填充二级图片文件夹
        imageFolder.add(pngFolder);
        imageFolder.add(gifFolder);
        //填充二级文档文件夹
        documentFolder.add(testHtml);
        documentFolder.add(testJS);
        System.out.println(root.getInfo());
        //打印出来
        getChildrenInfo(root.getChildren(), 1);

    }

    /**
     * 递归遍历文件
     * @param arrayList
     */
    @SuppressWarnings("rawtypes")
    private static void getChildrenInfo(ArrayList  arrayList , int level){

        int length = arrayList.size();
        for(int m = 0;m<length;m++){
            Object item = arrayList.get(m);
            //如果是叶子节点就直接打印出来名称
            if(item instanceof File){
                System.out.println(printBlank(level)+ "文件  : " +  ((File) item).getInfo());
            }else {
                //如果是分支节点就先打印分支节点的名称,再递归遍历子节点
                System.out.println(printBlank(level)  + "文件夹  : " + ((Folder)item).getInfo());
                getChildrenInfo(((Folder)item).getChildren() , level +1);
            }

        }

    }

    private static String printBlank(int level) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < level; i++) {
            sb.append("*");
        }
        return sb.toString();
    }

}

 

 适配器模式

系统需要使用现有的类,而此类的接口不符合系统的需要。适配器将一个对象包装起来用以改变其接口  

//已经存在的类
public class Phone {
    public void typecPhone() {
        System.out.println("信息从Typec口的手机输出。");
    }
}

//适配接口
public interface Vga {
    void vgaInterface();
}

// 实现一个Type-c转VGA适配器,
public class Typec2Vga implements Vga{

    private Phone phone;
    
    public Typec2Vga(Phone phone) {
        // TODO Auto-generated constructor stub
        this.phone = phone;
    }
    
    @Override
    public void vgaInterface() {
        // TODO Auto-generated method stub
        if(phone != null) {
            phone.typecPhone();
            System.out.println("接收到Type-c口信息,信息转换成VGA接口中...");
            System.out.println("信息已转换成VGA接口,显示屏可以对接。");
        }
    }
}

public class MainClass {

    
    public static void main(String[] args) {
        
        Phone phone = new Phone();
        Vga vga = new Typec2Vga(phone);
        vga.vgaInterface();
    }
}

 

外观模式

为子系统中的一组接口提供了一个统一的访问接口,使得子系统更加容易使用

public class CPU {

    public void  start() {
        System.out.println("CPU start");
    }
    
    public void shutdown() {
        System.out.println("CPU shutdown");
    }
}

public class Disk {

    public void  start() {
        System.out.println("Disk start");
    }
    
    public void shutdown() {
        System.out.println("Disk shutdown");
    }
}

public class Memory {
    
    public void  start() {
        System.out.println("Memory start");
    }
    
    public void shutdown() {
        System.out.println("Memory shutdown");
    }
}

//外观
public class Computer {

    private CPU cpu;
    
    private Memory memory;
    
    private Disk disk;

    public Computer(CPU cpu, Memory memory, Disk disk) {
        super();
        this.cpu = cpu;
        this.memory = memory;
        this.disk = disk;
    }
    
    public void start() {
        cpu.start();
        memory.start();
        disk.start();
    }

}

public class MainClass {

    public static void main(String[] args) {
        
        CPU cpu = new CPU();
        Memory memory = new Memory();
        Disk disk = new Disk();
        Computer  computer = new Computer(cpu, memory, disk);
        computer.start();
        
    }

    
}

 

享元模式

通过共享技术来有效的支持大量细粒度的对象,为了尽量不创建多余的对象【线程池技术就是采用的享元模式】

public class FlyweightModel {
    /*
     * 享元模式—围棋落子
     */
    public static void main(String[] args) {
        String color = "";
        int x = 0;
        int y = 0;
        WQFlyweight wqFlyweight;
        for (int i = 0; i < 5; i++) {
            x = (int) (19 * Math.random());
            y = (int) (19 * Math.random());
            if (color.equals("")) {
                color = "";
            } else {
                color = "";
            }
            wqFlyweight = WQFlyweightFactory.getWQFlyweight(color);
            if (wqFlyweight != null) {
                wqFlyweight.put(x, y);
            }
        }
    }
}

//享元模式实现围棋落子
//1、抽象享元类(外部状态(x,y))
interface WQFlyweight {
    void put(int x, int y);// 外部状态,棋子位置
}

//2、具体享元类(内部状态(黑,白))
class WQConFlyweight implements WQFlyweight {
    private String color;

    public WQConFlyweight(String color) {
        this.color = color;
    }

    @Override
    public void put(int x, int y) {
        System.out.println(color + "子:落于" + "" + x + "," + y + "" + "位置");
    }
}

//3、享元工厂类
class WQFlyweightFactory {
    // 确保内部状态实例只有两个
    private static WQFlyweight WHITE;
    private static WQFlyweight BLACK;

    private WQFlyweightFactory() {
    };

    public static WQFlyweight getWQFlyweight(String color) {
        if (color.equals("")) {
            if (WHITE == null) {
                WHITE = new WQConFlyweight("");
            }
            return WHITE;
        } else if (color.equals("")) {
            if (BLACK == null) {
                BLACK = new WQConFlyweight("");
            }
            return BLACK;
        }
        return null;
    }

}

 代理模式

客户端并不直接调用实际对象,而是通过调用代理来间接的调用实际对象

public interface Subject {
    void visit();
}

public class RealSubject implements Subject {

    private String name = "byhieg";
    @Override
    public void visit() {
        System.out.println(name);
    }
}

public class DynamicProxy implements InvocationHandler {
    private Object object;

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(object, args);
        return result;
    }
}

public class MainClass {

    public static void main(String[] args) {
        
        Subject realSubject = new RealSubject();
        DynamicProxy proxy = new DynamicProxy(realSubject);
        ClassLoader classLoader = realSubject.getClass().getClassLoader();
        Subject subject = (Subject) Proxy.newProxyInstance(classLoader, new  Class[]{Subject.class}, proxy);
        subject.visit();
        
    }
}

 

posted @ 2019-09-24 12:03  踏月而来  阅读(156)  评论(0编辑  收藏  举报