创建型设计模式
创建型模式抽象了实例化过程。它们帮助一个系统独立于如何创建、组合和表示它的那些对象。
创建型设计模式有5种
- 工厂方法模式
- 抽象工厂模式
- 建造者模式
- 原型模式
- 单例模式
设计模式之简单工厂模式
简单工厂模式定义
简单工厂模式分三种:普通工厂模式、多个工厂模式、静态工厂模式,用一个工厂来负责创建所有类的对象并初始化创建的对象。
普通工厂模式
通过传入的参数初始化相应的对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public interface MyInterface { public void print(); }
public class MyClassOne implements MyInterface { @Override public void print() { System.out.println("MyClassOne"); } }
public class MyClassTwo implements MyInterface { @Override public void print() { System.out.println("MyClassTwo"); } }
public MyInterface produce(String type) { if ("One".equals(type)) { return new MyClassOne(); } else if ("Two".equals(type)) { return new MyClassTwo(); } else { System.out.println("没有要找的类型"); return null; } }
public static void main(String[] args){ MyFactory factory = new MyFactory(); MyInterface myi = factory.produce("One"); myi.print(); }
|
多个工厂模式
多个工厂方法模式,是对普通工厂方法模式的改进,多个工厂方法模式就是提供多个工厂方法,分别创建对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class MyFactory { public MyInterface produceOne() { return new MyClassOne(); }
public MyInterface produceTwo() { return new MyClassTwo(); } }
public class FactoryTest {
public static void main(String[] args){ MyFactory factory = new MyFactory(); MyInterface myi = factory.produceOne(); myi.print(); }
}
|
静态工厂模式
静态工厂模式是对多个工厂模式的改进,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class MyFactory { public static MyInterface produceOne() { return new MyClassOne(); }
public static MyInterface produceTwo() { return new MyClassTwo(); } }
public class FactoryTest { public static void main(String[] args){ MyInterface myi = MyFactory.produceOne(); myi.print(); } }
|
设计模式之抽象工厂模式
简单工厂模式有一个问题就是每当想拓展时就需要对工厂类进行修改。违背了闭包原则。
抽象工厂模式会创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。
实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| public interface MyInterface { public void print(); }
public class MyClassOne implements MyInterface { @Override public void print() { System.out.println("MyClassOne戴尔"); } }
public class MyClassTwo implements MyInterface { @Override public void print() { System.out.println("MyClassTwo惠普"); } }
public interface Provider { public MyInterface produce(); }
public class MyFactoryOne implements Provider { @Override public MyInterface produce() { return new MyClassOne(); } }
public class MyFactoryTwo implements Provider { @Override public MyInterface produce() { return new MyClassTwo(); } }
public class FactoryTest { public static void main(String[] args){ Provider provider = new MyFactoryOne(); MyInterface myi = provider.produce(); myi.print(); } }
|
设计模式之单例模式
单例模式的定义
单例模式就是每个类只有一个实例
例如:windows在资源管理器操作文件的时候,必须是单例模式的.
单例模式的特点
- 单例类只能有一个实例
- 单例类需要自己创建自己唯一的实例
- 单例类需要给其他对象提供自己这个唯一的实例
比如读取配置文件的就需要使用单例模式
单例模式优点
- 减少了内存开销,避免了频繁创建和销毁实例
- 避免对资源的多重占用
单例模式缺点
- 不能继承
单例模式
饿汉式
在启动时就加载初始化实例,此处的私有构造方法是为了不让外部对其进行初始化
1 2 3 4 5 6 7 8 9 10 11 12
| public class Singleton1 { private Singleton1() {}
private static Singleton1 single = new Singleton1();
public static Singleton1 getInstance() { return single; } }
|
懒汉式
在代码处需要使用时进行初始化实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class Singleton2 {
private Singleton2() {}
private static Singleton2 single = null;
public static Singleton2 getInstance() { if(single == null){ single = new Singleton2(); } return single; } }
|
※在多线程模式中会出现问题
改进1:
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Singleton3 { private Singleton3() {}
private static Singleton3 single = null;
public static synchronized Singleton3 getInstance() { if(single == null){ single = new Singleton3(); } return single; } }
|
发现效率很低
改进2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class Singleton4 { private Singleton4() {}
private static Singleton4 single = null;
public static Singleton4 getInstance() { if (single == null) { synchronized (Singleton4.class) { if (single == null) { single = new Singleton4(); } } } return single; } }
|
静态内部类
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Singleton6 { private Singleton6() {}
private static class InnerObject{ private static Singleton6 single = new Singleton6(); } public static Singleton6 getInstance() { return InnerObject.single; } }
|
static静态代码块实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class Singleton7 { private Singleton7() {} private static Singleton7 single = null;
static{ single = new Singleton7(); } public static Singleton7 getInstance() { return single; } }
|
内部枚举类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class SingletonFactory { private enum EnmuSingleton{ Singleton; private Singleton8 singleton; private EnmuSingleton(){ singleton = new Singleton8(); } public Singleton8 getInstance(){ return singleton; } } public static Singleton8 getInstance() { return EnmuSingleton.Singleton.getInstance(); } }
class Singleton8{ public Singleton8(){} }
|
这种实现方式还没有被广泛采用,但这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。
一般情况下,不建议使用第 1 种和第 2 种懒汉方式,建议使用第 3 种饿汉方式。只有在要明确实现 lazy loading 效果时,才会使用第 5 种登记方式。如果涉及到反序列化创建对象时,可以尝试使用第 6 种枚举方式。如果有其他特殊的需求,可以考虑使用第 4 种双检锁方式。
设计模式之原型模式
原型模式概述
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
优点:
1、性能提高。 2、逃避构造函数的约束。
缺点:
1、配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。 2、必须实现 Cloneable 接口。
实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
| public abstract class Shape implements Cloneable { private String id; protected String type; abstract void draw(); public String getType(){ return type; } public String getId() { return id; } public void setId(String id) { this.id = id; } public Object clone() { Object clone = null; try { clone = super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return clone; } }
public class Rectangle extends Shape { public Rectangle(){ type = "Rectangle"; } @Override public void draw() { System.out.println("Inside Rectangle::draw() method."); } }
public class Square extends Shape { public Square(){ type = "Square"; } @Override public void draw() { System.out.println("Inside Square::draw() method."); } }
public class Circle extends Shape { public Circle(){ type = "Circle"; } @Override public void draw() { System.out.println("Inside Circle::draw() method."); } }
import java.util.Hashtable; public class ShapeCache { private static Hashtable<String, Shape> shapeMap = new Hashtable<String, Shape>(); public static Shape getShape(String shapeId) { Shape cachedShape = shapeMap.get(shapeId); return (Shape) cachedShape.clone(); } public static void loadCache() { Circle circle = new Circle(); circle.setId("1"); shapeMap.put(circle.getId(),circle); Square square = new Square(); square.setId("2"); shapeMap.put(square.getId(),square); Rectangle rectangle = new Rectangle(); rectangle.setId("3"); shapeMap.put(rectangle.getId(),rectangle); } }
public class PrototypePatternDemo { public static void main(String[] args) { ShapeCache.loadCache(); Shape clonedShape = (Shape) ShapeCache.getShape("1"); System.out.println("Shape : " + clonedShape.getType()); Shape clonedShape2 = (Shape) ShapeCache.getShape("2"); System.out.println("Shape : " + clonedShape2.getType()); Shape clonedShape3 = (Shape) ShapeCache.getShape("3"); System.out.println("Shape : " + clonedShape3.getType()); } }
|