目录
单例模式主要是为了避免因为创建了多个实例造成资源的浪费,且多个实例由于多次调用容易导致结果出现错误,而使用单例模式能够保证整个应用中有且只有一个实例。
单例模式主要是为了避免因为创建了多个实例造成资源的浪费,且多个实例由于多次调用容易导致结果出现错误,而使用单例模式能够保证整个应用中有且只有一个实例。
定义:只需要三步就可以保证对象的唯一性
对比定义:
饿汉式[可用]:SingletonEHan.java
-
-
- /**
- * Created by jingbin on 2016/10/27.
- * 1.单例模式的饿汉式[可用]
- * (1)私有化该类的构造函数
- * (2)通过new在本类中创建一个本类对象
- * (3)定义一个公有的方法,将在该类中所创建的对象返回
- *
- * 优点:从它的实现中我们可以看到,这种方式的实现比较简单,在类加载的时候就完成了实例化,避免了线程的同步问题。
- * 缺点:由于在类加载的时候就实例化了,所以没有达到Lazy Loading(懒加载)的效果,也就是说可能我没有用到这个实例,但是它
- * 也会加载,会造成内存的浪费(但是这个浪费可以忽略,所以这种方式也是推荐使用的)。
- */
-
- public class SingletonEHan {
-
- private SingletonEHan() {}
-
- /**
- * 1.单例模式的饿汉式[可用]
- */
- private static SingletonEHan singletonEHan = new SingletonEHan();
-
- public static SingletonEHan getInstance() {
- return singletonEHan;
- }
-
- // SingletonEHan instance= SingletonEHan.getInstance();
-
- /**
- * 2. 单例模式的饿汉式变换写法[可用]
- * 基本没区别
- */
- private static SingletonEHan singletonEHanTwo = null;
-
- static {
- singletonEHanTwo = new SingletonEHan();
- }
-
- public static SingletonEHan getSingletonEHan() {
- if (singletonEHanTwo == null) {
- singletonEHanTwo = new SingletonEHan();
- }
- return singletonEHanTwo;
- }
- // SingletonEHan instance= SingletonEHan.getSingletonEHan();
-
-
- }
含懒汉式[双重校验锁 推荐用]:SingletonLanHan.java
- private SingletonLanHan() {}
- private static SingletonLanHan singletonLanHanFour;
- public static SingletonLanHan getSingletonLanHanFour() {
- if (singletonLanHanFour == null) {
- synchronized (SingletonLanHan.class) {
- if (singletonLanHanFour == null) {
- singletonLanHanFour = new SingletonLanHan();
- }
- }
- }
- return singletonLanHanFour;
- }
- /**
- * Created by jingbin on 2016/10/28.
- * 7. 内部类[推荐用]
- *
- * 这种方式跟饿汉式方式采用的机制类似,但又有不同。
- * 两者都是采用了类装载的机制来保证初始化实例时只有一个线程。
- * 不同的地方:
- * 在饿汉式方式是只要Singleton类被装载就会实例化,
- * 内部类是在需要实例化时,调用getInstance方法,才会装载SingletonHolder类
- *
- * 优点:避免了线程不安全,延迟加载,效率高。
- */
-
- public class SingletonIn {
-
- private SingletonIn() {
- }
-
- private static class SingletonInHodler {
- private static SingletonIn singletonIn = new SingletonIn();
- }
-
- public static SingletonIn getSingletonIn() {
- return SingletonInHodler.singletonIn;
- }
- }
- /**
- * Created by jingbin on 2016/10/28.
- * 8. 枚举[极推荐使用]
- *
- * 这里SingletonEnum.instance
- * 这里的instance即为SingletonEnum类型的引用所以得到它就可以调用枚举中的方法了。
- 借助JDK1.5中添加的枚举来实现单例模式。不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象
- */
-
- public enum SingletonEnum {
-
- instance;
-
- private SingletonEnum() {
- }
-
- public void whateverMethod() {
-
- }
-
- // SingletonEnum.instance.method();
-
- }
建造模式是对象的创建模式。建造模式可以将一个产品的内部表象(internal representation)与产品的生产过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象。
需求:用户去汽车店购买汽车。
分析:汽车店根据每个用户的需求提取对应汽车
建造者超类:Builder
- public abstract class Builder {
-
- public abstract void setPart(String name, String type);
-
- public abstract Product getProduct();
- }
建造者对应实现类:ConcreteBuilder
- public class ConcreteBuilder extends Builder {
-
- private Product product = new Product();
-
- @Override
- public void setPart(String name, String type) {
- product.setName(name);
- product.setType(type);
- }
-
- @Override
- public Product getProduct() {
- return product;
- }
- }
店长Director取汽车:
- // 店长
- Director director = new Director();
- // 得到宝马汽车,内部实现提取宝马汽车的详情操作
- Product product = director.getBProduct();
- // 展示汽车信息
- product.showProduct();
简单列一下这个模式的家族:
1、静态工厂模式
2、简单工厂模式(店里买肉夹馍)
- /**
- * Created by jingbin on 2016/10/23.
- * 简单工厂模式
- */
-
- public class SimpleRoujiaMoFactory {
-
- public RoujiaMo creatRoujiaMo(String type) {
- RoujiaMo roujiaMo = null;
- switch (type) {
- case "Suan":
- roujiaMo = new ZSuanRoujiaMo();
- break;
- case "La":
- roujiaMo = new ZLaRoujiaMo();
- break;
- case "Tian":
- roujiaMo = new ZTianRoujiaMo();
- break;
- default:// 默认为酸肉夹馍
- roujiaMo = new ZSuanRoujiaMo();
- break;
- }
- return roujiaMo;
- }
- }
- public RoujiaMo creatRoujiaMo(String type) {
- RoujiaMo roujiaMo = null;
- switch (type) {
- case "Suan":
- roujiaMo = new ZSuanRoujiaMo();
- break;
- case "La":
- roujiaMo = new ZLaRoujiaMo();
- break;
- case "Tian":
- roujiaMo = new ZTianRoujiaMo();
- break;
- default:// 默认为酸肉夹馍
- roujiaMo = new ZSuanRoujiaMo();
- break;
- }
- return roujiaMo;
- }
3、工厂方法模式(开分店)
提供创建肉夹馍店抽象方法:RoujiaMoStore.java
- /**
- * Created by jingbin on 2016/10/24.
- *
- * 在北京和西安 开分店:
- * 工厂方法模式:
- * 定义:定义一个创建对象的接口,但由子类决定要实例化的类是哪一个。
- * 工厂方法模式把类实例化的过程推迟到子类。
- *
- * 对照定义:
- 1、定义了创建对象的一个接口:public abstract RouJiaMo sellRoujiaMo(String type);
- 2、由子类决定实例化的类,可以看到我们的馍是子类生成的。
- */
-
- public abstract class RoujiaMoStore {
-
- public abstract RoujiaMo sellRoujiaMo(String type);
-
- // public RoujiaMo sellRoujiaMo(String type) {
- //
- // RoujiaMo roujiaMo = creatRoujiaMo(type);
- // roujiaMo.prepare();
- // roujiaMo.fire();
- // roujiaMo.pack();
- // return roujiaMo;
- //
- // }
-
- }
public abstract RoujiaMo sellRoujiaMo(String type);
具体实现抽象方法:XianRoujiaMoStore.java
- /**
- * Created by jingbin on 2016/10/24.
- * 西安肉夹馍店 让分店自己去卖自己口味的肉夹馍
- */
-
- public class XianRoujiaMoStore extends RoujiaMoStore {
-
- private XianSimpleRoujiaMoFactory factory;
-
- public XianRoujiaMoStore(XianSimpleRoujiaMoFactory factory) {
- this.factory = factory;
- }
-
- public RoujiaMo sellRoujiaMo(String type) {
-
- RoujiaMo roujiaMo = factory.creatRoujiaMo(type);
- roujiaMo.prepare();
- roujiaMo.fire();
- roujiaMo.pack();
- return roujiaMo;
- }
-
- // @Override
- // public RoujiaMo creatRoujiaMo(String type) {
- //
- // RoujiaMo roujiaMo = null;
- // switch (type) {
- // case "suan":
- // roujiaMo = new XianSuanRoujiMo();
- // break;
- // case "tian":
- // roujiaMo = new XianKuRoujiMo();
- // break;
- // case "la":
- // roujiaMo = new XianlaRoujiMo();
- // break;
- // default:// 默认为 西安 酸肉夹馍
- // roujiaMo = new XianSuanRoujiMo();
- // break;
- // }
- // return roujiaMo;
- // }
- }
分店依旧使用简单工厂模式:XianSimpleRoujiaMoFactory.java
- /**
- * Created by jingbin on 2016/10/23.
- * 西安 简单工厂模式:
- * 用来西安店生产自己店里的肉夹馍
- */
-
- public class XianSimpleRoujiaMoFactory {
-
- public RoujiaMo creatRoujiaMo(String type) {
- RoujiaMo roujiaMo = null;
- switch (type) {
- case "Suan":
- roujiaMo = new XianSuanRoujiMo();
- break;
- case "La":
- roujiaMo = new XianKuRoujiMo();
- break;
- case "Tian":
- roujiaMo = new XianlaRoujiMo();
- break;
- default:// 默认为酸肉夹馍
- roujiaMo = new XianSuanRoujiMo();
- break;
- }
- return roujiaMo;
- }
- }
- /**
- * Created by jingbin on 2016/10/26.
- * 4、抽象工厂模式:
- * 定义:提供一个接口,用于创建相关的或依赖对象的家族,而不需要明确指定具体类。
- * 这定义有点绕口,算了,还是拿例子来说。
- * 继续卖肉夹馍,咱们生意这么好,难免有些分店开始动歪脑子,开始使用劣质肉等,砸我们的品牌。
- * 所以我们要拿钱在每个城市建立自己的原料场,保证高质量原料的供应。
- */
-
- public interface RoujiaMoYLFactory {
-
- /**
- * 生产肉
- */
- public Meet creatMeet();
-
- /**
- * 生产一些原料
- */
- public YuanLiao creatYuanLiao();
- }
- /**
- * Created by jingbin on 2016/10/26.
- * 西安的肉夹馍原料工厂,是西安的特色原料,还有其他分店的特色原料
- */
-
- public class XianRoujiaMoYLFoctory implements RoujiaMoYLFactory {
-
- @Override
- public Meet creatMeet() {
- return new XianFreshMeet();
- }
-
- @Override
- public YuanLiao creatYuanLiao() {
- return new XianTeSeYuanLiao();
- }
- }
- import android.util.Log;
-
- /**
- * Created by jingbin on 2016/10/22.
- */
-
- public abstract class RoujiaMo {
-
- protected String name;
-
- /**
- * 准备工作
- */
- public void prepare(RoujiaMoYLFactory roujiaMoYLFactory) {
- Meet meet = roujiaMoYLFactory.creatMeet();
- YuanLiao yuanLiao = roujiaMoYLFactory.creatYuanLiao();
-
- Log.e("---RoujiaMo:", "使用官方的原料 ---" + name + ": 揉面-剁肉-完成准备工作 yuanLiao:"+meet+"yuanLiao:"+yuanLiao);
- }
-
- /**
- * 秘制设备--烘烤2分钟
- */
- public void fire() {
- Log.e("---RoujiaMo:", name + ": 肉夹馍-专用设备-烘烤");
- }
-
- /**
- * 使用你们的专用袋-包装
- */
- public void pack() {
- Log.e("---RoujiaMo:", name + ": 肉夹馍-专用袋-包装---end");
- }
- }
- /**
- * 准备工作
- */
- public void prepare(RoujiaMoYLFactory roujiaMoYLFactory) {
- Meet meet = roujiaMoYLFactory.creatMeet();
- YuanLiao yuanLiao = roujiaMoYLFactory.creatYuanLiao();
- Log.e("---RoujiaMo:", "使用官方的原料 ---" + name + ": 揉面-剁肉-完成准备工作 yuanLiao:"+meet+"yuanLiao:"+yuanLiao);
- }
原型模式是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。
以获取多种形状为例,共分四步:
1、创建一个实现了 Cloneable 接口的抽象类。Shape(implements Cloneable)
- public abstract class Shape implements Cloneable {
-
- private String id;
- protected String type;
-
- public abstract void draw();
-
- public String getId() {
- return id;
- }
-
- public void setId(String id) {
- this.id = id;
- }
-
- @Override
- public Object clone() {
- Object object = null;
- try {
- object = super.clone();
- } catch (CloneNotSupportedException e) {
- Log.e("--", e.getMessage());
- }
- return object;
- }
- }
2、创建扩展了上面抽象类的实体类。Circle、Rectangle、Square
- public class Circle extends Shape {
-
- public Circle() {
- type = "Circle";
- }
-
- @Override
- public void draw() {
- Log.e("---", "Inside Circle::draw() method.");
- }
-
- }
-
- /**
- * Created by jingbin on 2020-01-31.
- * 2. 创建扩展了上面抽象类的实体类。Rectangle 矩形
- */
- public class Rectangle extends Shape {
-
- public Rectangle() {
- type = "Rectangle";
- }
-
- @Override
- public void draw() {
- Log.e("---", "Inside Rectangle::draw() method.");
- }
-
-
- }
- /**
- * Created by jingbin on 2020-01-31.
- * 2. 创建扩展了上面抽象类的实体类。Square 正方形
- */
- public class Square extends Shape {
-
- public Square() {
- type = "Square";
- }
-
- @Override
- public void draw() {
- Log.e("---", "Inside Square::draw() method.");
- }
-
-
- }
3、创建一个类,从数据库获取实体类,并把它们存储在一个 Hashtable 中。ShapeCache
- public class ShapeCache {
-
- private static Hashtable
shapeMap = new Hashtable(); -
- public static Shape getShape(String shapeId) {
- Shape shapeCache = shapeMap.get(shapeId);
- return (Shape) shapeCache.clone();
- }
-
- // 对每种形状都运行数据库查询,并创建该形状
- // shapeMap.put(shapeKey, shape);
- // 例如,我们要添加三种形状
- public static void loadCache() {
- Circle circle = new Circle();
- circle.setId("1");
- shapeMap.put(circle.getId(), circle);
-
- Rectangle rectangle = new Rectangle();
- rectangle.setId("2");
- shapeMap.put(rectangle.getId(), rectangle);
-
- Square square = new Square();
- square.setId("3");
- shapeMap.put(square.getId(), square);
- }
- }
4、使用 ShapeCache 类来获取存储在 Hashtable 中的形状的克隆。
- // 使用 ShapeCache 类来获取存储在 Hashtable 中的形状的克隆。
- ShapeCache.loadCache();
- Shape shapeCache1 = ShapeCache.getShape("1");
- Shape shapeCache2 = ShapeCache.getShape("2");
- Shape shapeCache3 = ShapeCache.getShape("3");
相关代码github地址:GitHub - youlookwhat/DesignPattern: 📚 Java 23种设计模式全归纳