设计模式之创建型模式
一、单例模式
单例设计模式(Singleton Design Pattern)理解起来非常简单。一个类只允许创建一个对象(或者实例),那这个类就是一个单例类,这种设计模式就叫作单例设计模式,简称单例模式。
实现方式:
- 饿汉模式
public class IdGenerator{
private AtomicLong id = new AtomicLong(0);
privatestaticfinal IdGenerator instance = new IdGenerator();
private IdGenerator(){}
public static IdGenerator getInstance(){
return instance;
}
public long getId(){
return id.incrementAndGet();
}
}
- 懒汉模式
public class IdGenerator {
private AtomicLong id = new AtomicLong(0);
privat estatic IdGenerator instance;
private IdGenerator() {
}
public static synchronized IdGenerator getInstance() {
if (instance == null) {
instance = new IdGenerator();
}
return instance;
}
public long getId(){
return id.incrementAndGet();
}
}2
- 双重检查
public class IdGenerator{
private AtomicLong id = new AtomicLong(0);
privatestatic IdGenerator instance;
private IdGenerator(){}
publicstatic IdGenerator getInstance(){
if (instance == null) {
synchronized(IdGenerator.class) {
// 此处为类级别的锁
if (instance == null) {
instance = new IdGenerator();
}
}
}return instance;
}
public long getId(){
return id.incrementAndGet();
}
}
- 静态内部类
public class IdGenerator{
private AtomicLong id = new AtomicLong(0);
private IdGenerator(){}
private static class SingletonHolder{
private static final IdGenerator instance = new IdGenerator();
}
public static IdGenerator getInstance(){
return SingletonHolder.instance;
}
public long getId(){
return id.incrementAndGet();
}
}
- 枚举
public enum IdGenerator {
INSTANCE;
private AtomicLong id = new AtomicLong(0);
public long getId(){
return id.incrementAndGet();
}
}
二、工厂模式
简单工厂
public class RuleConfigFactory{
privatestaticfinal Map<String, RuleConfigParser> cachedParsers = new HashMastatic {
cachedParsers.put("json", new JsonRuleConfigParser());
cachedParsers.put("xml", new XmlRuleConfigParser());
cachedParsers.put("yaml", new YamlRuleConfigParser());
cachedParsers.put("properties", new PropertiesRuleConfigParser());
}
public static IRuleConfigParser createParser(String configFormat){
if (configFormat == null || configFormat.isEmpty()) {
return null;
//返回null还是IllegalArgumentException全凭你自己说了算
}
IRuleConfigParser parser = cachedParsers.get(configFormat.toLowerCase());
return parser;
}
}
个人理解:
简单工厂方法,在工厂类中集成了各种类创建的规则,在工厂类中有严格的if语句判断,虽然违背了开闭原则,但是代码可读性较强。
工厂方法
为了去除简单工厂中if-else 语句的判断,利用多态派生出各种各样的具体工厂。
public interface IRuleConfigParserFactory{
IRuleConfigParser createParser();
}
public class JsonRuleConfigParserFactory implements IRuleConfigParserFactory{
@Override
public IRuleConfigParser createParser(){
return new JsonRuleConfigParser();
}
}
public class XmlRuleConfigParserFactory implements IRuleConfigParserFactory{
@Override
public IRuleConfigParser createParser(){
return new XmlRuleConfigParser();
}
}
总结:
1、简单工厂模式中包含判断什么对象的逻辑,而工厂方法模式则需要调用者判断要实例化什么具体类型的工厂进而创建出想要的对象。当增加新类时,简单工厂模式需要修改工厂类,而工厂方法模式不需要,因此工厂方法模式遵守了开闭原则,而简单工厂模式没遵守。
2、简单工厂模式因为采用了静态方法,所以不利于继承,而工厂方法模式恰恰相反,需要利用到继承来从抽象工厂中派生出各种各样的具体工厂。
抽象工厂
参考:https://www.runoob.com/design-pattern/abstract-factory-pattern.html
三、原型模式
如果对象的创建成本比较大,而同一个类的不同对象之间差别不大(大部分字段都相同),在这种情况下,我们可以利用对已有对象(原型)进行复制(或者叫拷贝)的方式,来创建新对象,以达到节省创建时间的目的。这种基于原型来创建对象的方式就叫作原型设计模式,简称原型模式。
原型模式有两种实现方法,深拷贝和浅拷贝。浅拷贝只会复制对象中基本数据类型数据和引用对象的内存地址,不会递归地复制引用对象,以及引用对象的引用对象…而深拷贝得到的是一份完完全全独立的对象。所以,深拷贝比起浅拷贝来说,更加耗时,更加耗内存空间。
-
浅拷贝
在 Java 语言中,Object 类的 clone() 方法执行的就是我们刚刚说的浅拷贝。它只会拷贝对象中的基本数据类型的数据(比如,int、long),以及引用对象(SearchWord)的内存地址,不会递归地拷贝引用对象本身。 -
深拷贝
深拷贝主要实现方式有两种,第一种是递归复制对象中的引用对象,直至对象中只包含基本类型,不包含引用类型。第二种是采用对象序列化的方式,先将对象序列化,然后反序列化成新的对象。
public Object deepCopy(Object object) {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(object);
ByteArrayInputStream bi = new
ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
return oi.readObject();
}
本文地址:https://blog.csdn.net/Faker_Wang/article/details/110248532