设计模式

参考资料 java 设计模式 刘伟

面向对象设计原则

  • 单一职责原则 (拆职责糅杂的类)
  • 开闭原则 (方便扩展)
  • 里氏代换 (大->小,必要条件)
  • 依赖倒转 (就换个依赖对象,更抽象的对象)
  • 接口隔离 (拆大接口,以免低复用,多无用代码)
  • 合成复用 (组合/聚合,继承)

简单工厂模式(工厂模式的基础)

有名静态工厂模式,静态工厂方法模式

简单手打一下

abstract class Product{

}
class pro1 extends Product{
    public  pro1(){
        System.out.println("create pro1");
    }
}
class pro2 extends Product{
    public  pro2(){
        System.out.println("create pro2");
    }
}
class SimpleFactory{
    public static Product getProduct(String args){
        Product product = null;
        if(args.equalsIgnoreCase("pro1")){//忽略大小写
            product = new pro1();
        }else if(args.equalsIgnoreCase("pro2")){
            product = new pro2();
        }
        return product;
    }
}
public class Main {
    public static void main(String args[]){
        Product pro= SimpleFactory.getProduct("pro1");
        pro= SimpleFactory.getProduct("pro2");
    }
}

说实话,静态工厂我还用的不多,就转类型的时候用用,梳理一下优缺点吧。

优势:
1.创建对象和使用对象的分离
2.只要记住对应工厂的参数
3.引入配置文件,在不修改客户端代码的情况下更换和增加新的具体产品类(额..还没试过)

劣势:
1.工厂中集中了所有产品的创建逻辑,负担有点重
2.类会增加(这我怎么觉得无关紧要啊)
3.不利于增加产品线(就是抽象的产品,不是具体类)
4.因为使用了静态工厂方法,工厂角色无法形成继承关系

工厂方法模式



//就设计一个多种格式图片读取的程序
interface Pic{
    public void readPic();
}

class jpg implements Pic{
    @Override
    public void readPic(){
        System.out.println("jpg");
    }
}

class png implements Pic{
    @Override
    public void readPic(){
        System.out.println("png");
    }
}

interface PicFactory{
    public Pic createPic();
}

class JpgFactory implements PicFactory{
    @Override
    public Pic createPic(){
        System.out.println("----creating jpg-----");
        Pic pic = new jpg();
        return pic;
    }
}

class PngFactory implements PicFactory{
    @Override
    public Pic createPic() {
        System.out.println("----creating png-----");
        Pic pic = new png();
        return pic;
    }
}


public class Main {

    public static void main(String args[]){
        PicFactory picFactory=new JpgFactory();
        Pic pic;
        pic=picFactory.createPic();
        pic.readPic();
    }

}

利用反射和xml文件后

interface Pic{
    public void readPic();
}

class jpg implements Pic{
    @Override
    public void readPic(){
        System.out.println("jpg");
    }
}

class png implements Pic{
    @Override
    public void readPic(){
        System.out.println("png");
    }
}

interface PicFactory{
    public Pic createPic();
}

class JpgFactory implements PicFactory{
    @Override
    public Pic createPic(){
        System.out.println("----creating jpg-----");
        Pic pic = new jpg();
        return pic;
    }
}

class PngFactory implements PicFactory{
    @Override
    public Pic createPic() {
        System.out.println("----creating png-----");
        Pic pic = new png();
        return pic;
    }
}


public class Main {
    public static void main(String args[]){
//        PicFactory picFactory=new JpgFactory();
        PicFactory picFactory= (PngFactory)XMLUtil.getBean();
        Pic pic=picFactory.createPic();
        pic.readPic();
    }
}
package com.example.demo.Learning.design.Factory;

import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;


public class XMLUtil {
    public static Object getBean(){
        try{
            DocumentBuilderFactory dFactory=DocumentBuilderFactory.newInstance();
            DocumentBuilder builder =dFactory.newDocumentBuilder();
            Document doc=builder.parse(new File("src/main/java/com/example/demo/Learning/design/Factory/config.xml"));

            //
            NodeList nl = doc.getElementsByTagName("className");
//            System.out.println(nl.getLength());
            Node classnode = nl.item(1).getFirstChild();
            String cName=classnode.getNodeValue();
            System.out.println(cName);
            Class c=Class.forName("com.example.demo.Learning.design.Factory."+cName);
            Object obj=c.newInstance();
            return obj;

        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }
}

特点:每一个工厂只生产一类物品,后期扩展的时候只需增加工厂就可以了,就是烦,每加一个物品都得加一个工厂,双倍的快乐。

//多个系统多个游戏操作和界面操作

interface OperationController{
    public void display();
}
interface InterfaceController{
    public void display();
}
class SymbianOperation implements OperationController{
    @Override
    public void display(){
        System.out.println("塞班游戏操作");
    }
}
class AndroidOperation implements OperationController{
    @Override
    public void display(){
        System.out.println("安卓游戏操作");
    }
}
class WindowsOperation implements OperationController{
    @Override
    public void display() {
        System.out.println("windows游戏操作");
    }
}
class SymbianInterface implements InterfaceController{
    @Override
    public void display() {
        System.out.println("塞班界面操作");
    }
}
class AndroidInterface implements InterfaceController{
    @Override
    public void display() {
        System.out.println("安卓界面操作");
    }
}
class WindowsInterface implements InterfaceController{
    @Override
    public void display() {
        System.out.println("windows界面操作");
    }
}

interface SystemFactory{ //抽象工厂 系统
    public OperationController createOperationController();
    public InterfaceController createInterfaceController();
}

//具体工厂 三个系统
class  SymbianFactory implements SystemFactory{
    @Override
    public OperationController createOperationController() {
        return new SymbianOperation();
    }

    @Override
    public InterfaceController createInterfaceController() {
        return new SymbianInterface();
    }
}
class AndroidFactory implements SystemFactory{
    @Override
    public OperationController createOperationController() {
        return new AndroidOperation();
    }

    @Override
    public InterfaceController createInterfaceController() {
        return new AndroidInterface();
    }
}


public class Main {
    public static void main(String[] args){
        SystemFactory systemFactory=new SymbianFactory();
        OperationController operationController = systemFactory.createOperationController();
        InterfaceController interfaceController = systemFactory.createInterfaceController();
        operationController.display();
        interfaceController.display();
    }
}

有意思,还是通过巧妙地生产抽象工厂和基类的调用来解决修改,扩张困难的问题。

单例模式

//饿汉
class hun{
    private static hun instance=new hun();
    private hun(){}
    public static hun getInstance(){
        return instance;
    }
}
//lazy 但线程不安全
class lazy{
    private static lazy instance=null;
    private lazy(){}
    public static lazy getInstance(){
        if(instance==null){
            instance = new lazy();
        }
        return instance;
    }
}
//lazy 线程安全
class safelazy{
    private static volatile safelazy instance=null;
    private safelazy(){}
    public static safelazy getInstance(){
        if(instance==null){
            synchronized (safelazy.class){
                if(instance==null){
                    instance = new safelazy();
                }
            }
        }
        return instance;
    }
}
//jvm 语言特性
class jvmsafe{
    private jvmsafe(){}
    private static class HolderClass{
        private final static jvmsafe instance = new jvmsafe();
    }
    public static jvmsafe getInstance(){
        return HolderClass.instance;
    }
}

public class Main {
    public static void main(String[] args){
//        hun ex1 = hun.getInstance();
//        hun ex2 = hun.getInstance();
//        System.out.println(ex1==ex2);

//        lazy ex3=lazy.getInstance();
//        lazy ex4=lazy.getInstance();
//        System.out.println(ex3==ex4);

//        safelazy ex3=safelazy.getInstance();
//        safelazy ex4=safelazy.getInstance();
//        System.out.println(ex3==ex4);

        jvmsafe ex3=jvmsafe.getInstance();
        jvmsafe ex4=jvmsafe.getInstance();
        System.out.println(ex3==ex4);
    }
}

Q:java虚拟机是如何保证每个类只能初始化一次呢?

原型模式

就是克隆,保存副本嘛

最为简单的一个例子



class Proto implements Cloneable{
    private String name;
    private String data;

    public String getName() {
        return name;
    }

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

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }
    public Proto clone(){
        Object obj=null;
        try{
            obj = super.clone();
            return (Proto)obj;
        }catch (Exception e){
            return null;
        }
    }
}

public class Main {
    public static void main(String[] args){
        Proto proto = new Proto();
        proto.setData("DataProto");
        proto.setName("NameProto");

        Proto instance1 = proto.clone();
        Proto instance2 = proto.clone();
//        System.out.println(instance1==instance2);
        System.out.println(instance1.getData());
        System.out.println(instance1.getName());

    }
}

深拷贝

    public Proto deepclone() throws IOException, ClassNotFoundException, OptionalDataException {
        ByteArrayOutputStream bao = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bao);
        oos.writeObject(this);
        oos.close();
        ByteArrayInputStream bis = new ByteArrayInputStream(bao.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return (Proto) ois.readObject();
    }

建造者模型

添加新评论