白话设计模式

2019-09-29  本文已影响0人  小道萧兮

所谓的设计模式(Design Pattern)其实是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。

所以你可能完全没学过设计模式也能写出很好的代码,设计模式只是解决问题的一种思路,你完全可以有自己的思路。但是了解一些常见的设计模式,肯定是对代码开发有帮助或者有启发作用。

一、单例模式

简单点说,就是一个应用程序中,某个类的实例对象只有一个,你没有办法去new,因为构造器是被private修饰的,一般通过getInstance()的方法来获取它们的实例。getInstance()的返回值是同一个对象的引用,并不是一个新的实例。

// 懒汉式
public class Singleton {
    private static Singleton instance;
    private Singleton (){}
    public static synchronized Singleton getInstance() {
        if (instance == null) instance = new Singleton();
        return instance;
    }
}

// 饿汉式
public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton () { }  
    public static Singleton getInstance() {  
        return instance;  
    }  
}

// 枚举
// 这种方式是Effective Java作者Josh Bloch 提倡的方式,
// 它不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象
public enum Singleton {  
     INSTANCE;  
     public void whateverMethod() {  }  
}

// 双重校验锁
public class Singleton {
    private volatile static Singleton singleton;
    private Singleton() { }
    public static Singleton getInstance() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null)
                    singleton = new Singleton2();
            }
        }
        return singleton;
    }
}

二、装饰者模式

对已有的业务逻辑进一步的封装,使其增加额外的功能,如Java中的IO流就使用了装饰者模式,用户在使用的时候,可以任意组装,达到自己想要的效果。

举个栗子,我想吃三明治,首先我需要一根香肠,我喜欢吃奶油,在香肠上面加一点奶油,再放一点蔬菜,最后再用两片面包夹一下,很丰盛的一顿午饭,营养又健康。

首先,我们需要写一个Food类,让其他所有食物都来继承这个类:

public class Food {

   private String food_name;

   public Food() { }

   public Food(String food_name) {
       this.food_name = food_name;
   }

   public String make() {
       return food_name;
   }
}

然后我们写几个子类继承它:

// 面包类
public class Bread extends Food {

   private Food basic_food;

   public Bread(Food basic_food) {
       this.basic_food = basic_food;
   }

   public String make() {
       return basic_food.make() + "+面包";
   }
}

// 奶油类
public class Cream extends Food {

   private Food basic_food;

   public Cream(Food basic_food) {
       this.basic_food = basic_food;
   }

   public String make() {
       return basic_food.make() + "+奶油";
   }
}

// 蔬菜类
public class Vegetable extends Food {

   private Food basic_food;

   public Vegetable(Food basic_food) {
       this.basic_food = basic_food;
   }

   public String make() {
       return basic_food.make() + "+蔬菜";
   }
}

这几个类都是差不多的,构造方法传入一个Food类型的参数,然后在make方法中加入一些自己的逻辑,如果你还是看不懂为什么这么写,看看Test类是怎么写的,一看你就明白了

public class Test {
   public static void main(String[] args) {
       Food food = new Bread(new Vegetable(new Cream(new Food("香肠"))));
       System.out.println(food.make());
   }
}

一层一层封装,我们从里往外看:最里面 new 了一个香肠,在香肠的外面我包裹了一层奶油,在奶油的外面我又加了一层蔬菜,最外面我放的是面包,是不是很形象?这个设计模式简直跟现实生活中一摸一样。

三、工厂模式

简单工厂模式:一个抽象的接口,多个抽象接口的实现类,一个工厂类,用来实例化抽象的接口。

// 抽象产品类
abstract class Car {
   public void run();
   public void stop();
}

// 具体实现类
class Benz implements Car {
   public void run() {
       System.out.println("Benz开始启动了……");
   }

   public void stop() {
       System.out.println("Benz停车了……");
   }
}

class Ford implements Car {
   public void run() {
       System.out.println("Ford开始启动了……");
   }

   public void stop() {
       System.out.println("Ford停车了……");
   }
}

// 工厂类
class Factory {
   public static Car getCarInstance(String type) {
       Car c = null;
       if ("Benz".equals(type))
           c = new Benz();
       else if ("Ford".equals(type))
           c = new Ford();
       return c;
   }
}

public class Test {
   public static void main(String[] args) {
       Car c = Factory.getCarInstance("Benz");
       c.run();
       c.stop();
   }
}

四、代理模式(proxy)

代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。

举个具体的例子,到了一定的年龄,我们就要结婚,结婚是一件很麻烦的事情,可能会找司仪来主持婚礼,显得热闹,婚庆公司打算怎么安排婚礼的节目,在婚礼完毕以后婚庆公司会做什么,我们一概不知。别担心,我们只要把钱给人家,人家会把事情给我们做好。所以,这里的婚庆公司相当于代理角色。

代码实现请看:

// 代理接口
public interface ProxyInterface {
    // 需要代理的是结婚这件事,如果还有其他事情需要代理,也可以写
    void marry();
}

我们看看婚庆公司的代码:

public class WeddingCompany implements ProxyInterface {

    private ProxyInterface proxyInterface;

    public WeddingCompany(ProxyInterface proxyInterface) {
        this.proxyInterface = proxyInterface;
    }

    @Override
    public void marry() {
        System.out.println("我们是婚庆公司的");
        System.out.println("我们在做结婚前的准备工作");
        System.out.println("节目彩排...");
        System.out.println("工作人员分工...");
        System.out.println("可以开始结婚了");
        proxyInterface.marry();
        System.out.println("结婚完毕,我们需要做后续处理,你们可以回家了,其余的事情我们公司来做");
    }
}

婚庆公司需要做的事情很多,我们再看看结婚家庭的代码:

public class NormalHome implements ProxyInterface{
    @Override
    public void marry() {
        System.out.println("我们结婚啦~");
    }
}

这个已经很明显了,结婚家庭只需要结婚,而婚庆公司这个代理要包揽一切准备工作,也就是说把许多要做的事情外包给其他人做,这就是代理模式。

来看看测试类代码:

public class Test {
    public static void main(String[] args) {
        ProxyInterface proxyInterface = new WeddingCompany(new NormalHome());
        proxyInterface.marry();
    }
}
上一篇 下一篇

猜你喜欢

热点阅读