设计模式之创建型模式
1、简单工厂模式
/** * 简单工厂类: * 优点:简单工厂类实现了对象创建和使用的分离,客户端可以免除直接创建产品对象的职责 * 缺点:当引入新产品时,需要修改静态方法,通过传入不同的参数创建不同的产品,需要修改工程类,违背“开闭原则” */ public class Factory { public static Product getProduct(String type){ if(type.equals("A")){ return new Product1(); }else if(type.equals("B")){ return new Product2(); }else return null; } } /** * 抽象产品类 */ public abstract class Product { public abstract void methodDiff(); public void methodSame(){ System.out.println("methodSame"); } } /** * 具体产品类 */ public class Product1 extends Product{ @Override public void methodDiff() { System.out.println("product1"); } } /** * 具体产品类 */ public class Product2 extends Product{ @Override public void methodDiff() { System.out.println("product2"); } } public class Test { public static void main(String[] args)throws Exception{ Product product=Factory.getProduct("A"); product.methodSame(); product.methodDiff(); } }
2、工厂方法模式
/** * 方法模式: * 优点:加入新产品时,无需修改抽象工厂 * 缺点:增加新产品时,需要增加具体工厂类和具体工厂类,类的个数成对增加 */ /** * 抽象工厂类 */ public interface Factory { public Product factoryMethod(); } /** * 具体工厂 */ public class ConcreteFactory implements Factory { @Override public Product factoryMethod() { return new ConcreteProduct(); } } /** * 抽象产品类 */ public abstract class Product { public abstract void methodDiff(); public void methodSame(){ System.out.println("methodSame"); } } public class ConcreteProduct extends Product { @Override public void methodDiff(){ System.out.println("ConcreteProduct"); } } public class Test { public static void main(String[] args){ Factory factory=new ConcreteFactory(); Product product=factory.factoryMethod(); product.methodDiff(); product.methodSame(); } }
3、抽象工厂模式
/** * 抽象工厂模式: * 优点:相比工厂方法模式,如果新增产品减少了类的创建 * 缺点:如果新增产品,则需要修改抽象工厂类和具体工厂 */ /* 抽象工厂类:生命了用于创建一族产品的方法,每一个方法对应一种产品 */ public interface AbstractFactory { ConcreteProductA getProductA(); ConcreteProductB getProductB(); } /** 具体工厂类:实现了抽象工厂中的方法,创建了一组具体产品 */ public class ConcreteFactory implements AbstractFactory { @Override public ConcreteProductA getProductA() { return new ConcreteProductA(); } @Override public ConcreteProductB getProductB(){ return new ConcreteProductB(); } } /** * 抽象产品 */ public interface AbstractProduct { void methodDiff(); } public class ConcreteProductA implements AbstractProduct { @Override public void methodDiff() { System.out.println("ConcreteProductA"); } } public class ConcreteProductB implements AbstractProduct { @Override public void methodDiff() { System.out.println("ConcreteProductB"); } } public class Test { public static void main(String[] args){ } }
4、单例模式
/** * 饿汉式(非延迟加载)单例:当类加载时会初始化静态变量singleton * 缺点:在类加载时就创建了对象。 * 说明:静态变量修饰的变量为EagerSingleton类的所有对象共享,在类加载时创建,并且不会被创建多次 */ public class EagerSingleton { private static final EagerSingleton singleton=new EagerSingleton(); private EagerSingleton(){} public static EagerSingleton getInstance(){ return singleton; } } /** * 懒汉式(延迟加载)单例 * 缺点:使用了加锁机制,降低了系统性能 */ public class LazySingleton { private static final LazySingleton singleton=null; private LazySingleton(){} /** * 方式一 * @return */ synchronized public static LazySingleton getInstance(){//synchronized关键字放在此位置,会导致系统性能降低 if(singleton == null){ return new LazySingleton(); } return singleton; } /** * 方式二:双重检查 * @return */ public static LazySingleton getInstance2(){ if(singleton == null){ synchronized (LazySingleton.class){ if(singleton == null){ return new LazySingleton(); } } } return singleton; } } /** * 在单例类中增加一个静态内部类,在该内部类中创建单例对象,在将该单例对象通过getInstance()方法返回给外部使用。此种方式集成了懒汉式和饿汉式的优点 * 说明:在外部类Sinleton加载时并不会立即加载内部类HolderClass,即不会创建instance。只有在第一次调用getInstance时,才会加载HolderClass并创建instance */ public class Singleton { private Singleton(){} private static class HolderClass{ private final static Singleton instance=new Singleton(); } public static Singleton getInstance(){ return HolderClass.instance; } }
5、原型模式
public class AttrClass { private String attr1; public String getAttr1() { return attr1; } public void setAttr1(String attr1) { this.attr1 = attr1; } } public class AttrClass1 implements Serializable { private String attr1; public String getAttr1() { return attr1; } public void setAttr1(String attr1) { this.attr1 = attr1; } } /** * 浅克隆模式:只会克隆值类型的成员变量,不会克隆原型对象的引用类型的成员,即原型对象和克隆对象会共用同一个引用类型的成员 */ public class ShallowPrototype implements Cloneable{ private String attr; private AttrClass attrClass; public String getAttr() { return attr; } public void setAttr(String attr) { this.attr = attr; } public AttrClass getAttrClass() { return attrClass; } public void setAttrClass(AttrClass attrClass) { this.attrClass = attrClass; } public ShallowPrototype clone(){ Object object=null; ShallowPrototype prototype=new ShallowPrototype(); try { object=super.clone(); }catch (CloneNotSupportedException e){ System.out.println("CloneNotSupportedException"); } return (ShallowPrototype)object ; } public static void main(String[] args){ AttrClass attrClass=new AttrClass(); attrClass.setAttr1("2"); ShallowPrototype shallowPrototype=new ShallowPrototype(); shallowPrototype.setAttr("1"); shallowPrototype.setAttrClass(attrClass); ShallowPrototype shallowPrototype1=shallowPrototype.clone(); System.out.println(shallowPrototype == shallowPrototype1);//false System.out.println(shallowPrototype.getAttr() == shallowPrototype1.getAttr());//true System.out.println(shallowPrototype.getAttrClass() == shallowPrototype1.getAttrClass());//true } } /** * 深克隆:会克隆原型对象的值类型和引用类型的成员,即原型对象和克隆对象不会共用同一个引用类型的成员 * 用序列化实现深克隆(序列化就是将对象写到流的过程,写到流中的对象是原有对象的一个拷贝,而原对象仍然存在于内存中) */ public class DeepPrototype implements Serializable,Cloneable { private String attr; private AttrClass1 attrClass1; public String getAttr() { return attr; } public void setAttr(String attr) { this.attr = attr; } public AttrClass1 getAttrClass1() { return attrClass1; } public void setAttrClass1(AttrClass1 attrClass1) { this.attrClass1 = attrClass1; } /** * 使用流实现深克隆 * @return */ public DeepPrototype clone(){ try{ //将对象写入流 ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream=new ObjectOutputStream(byteArrayOutputStream); objectOutputStream.writeObject(this); //将对象从流中取出 ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); ObjectInputStream objectInputStream=new ObjectInputStream(byteArrayInputStream); return (DeepPrototype) objectInputStream.readObject(); }catch (Exception e){ System.out.println("Exception"); } return null; } public static void main(String[] args){ AttrClass1 attrClass1=new AttrClass1(); attrClass1.setAttr1("2"); DeepPrototype deepPrototype=new DeepPrototype(); deepPrototype.setAttr("1"); deepPrototype.setAttrClass1(attrClass1); DeepPrototype deepPrototype1=deepPrototype.clone(); System.out.println(deepPrototype == deepPrototype1);//false System.out.println(deepPrototype.getAttr() == deepPrototype1.getAttr());//false System.out.println(deepPrototype.getAttrClass1() == deepPrototype1.getAttrClass1());//false } }
6、建造者模式(构建者模式)
public interface Builder { Product build(String id,String name); } public class ProductBuilder implements Builder { @Override public Product build(String id,String name) { Product product=new Product(); product.setId(id); product.setName(name); return product; } } public class Product { private String id; private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Product{" + "id='" + id + '\'' + ", name='" + name + '\'' + '}'; } } public class Test { public static void main(String[] args){ //构建者模式: //用户不需要关心具体的构建细节,只需创建相应的构建对象(ProductBuilder), // 并传入参数,即可得到产品类 ProductBuilder productBuilder =new ProductBuilder(); Product product= productBuilder.build("1","A"); System.out.println(product); } }