2018_02_07 JAVA設計模式---創建型模式

創建型模式一共分爲五種:工廠模式抽象工廠模式單例模式建造者模式,還有原型模式

工廠模式和抽象工廠模式一樣,都是用於生成對象的工廠,區別是,抽象工廠模式生產的是工廠,由工廠再產生對象,這兩種模式的好處是,需要對象的時候,只要在工廠中拿即可,只要知道需求對象的名字,但是,過多的工廠也會造成代碼的臃腫,因爲要想產生一類對象就需要一個類型的工廠,但需求更多時,工廠的代碼也會更繁瑣,會增加系統的複雜度(後面會介紹反射模式生成對象)

普通工廠模式代碼:(紅色部分爲反射模式生成對象)

package cn.jxliu.pattern.creational.factory;
public interface Animal {
	void eat();
}
package cn.jxliu.pattern.creational.factory;

/**
 * 創建工廠用於生成實體類的對象
 * 
 * @author Administrator 
 * 優點: 1、一個調用者想創建一個對象,只要知道其名稱就可以了。
 * 		2、擴展性高,如果想增加一個產品,只要擴展一個工廠類就可以。 
 * 		3、屏蔽產品的具體實現,調用者只關心產品的接口。
 * 缺點:每次增加一個產品時,都需要增加一個具體類和對象實現工廠,使得系統中類的個數成倍增加,在一定程度上增加了系統的複雜度,
 * 同時也增加了系統具體類的依賴。
 */
public class AnimalFactory {
	/**
	 * 普通模式
	 * @param animalType
	 * @return
	 */
	public Animal getAnimal(String animalType) {
		if (animalType == null) {
			return null;
		}
		if (animalType.equalsIgnoreCase("Cat")) {
			return new Cat();
		} else if (animalType.equalsIgnoreCase("Dog")) {
			return new Dog();
		} else if (animalType.equalsIgnoreCase("Tiger")) {
			return new Tiger();
		}
		return null;
	}
	
	/**
	 * 使用反射創建生成對象的工廠的好處,就是當需要生產不同的對象時,不需要再重新創建實體類對象實現接口了
	 * @param clazz
	 * @return
	 */
	public static Object getClass(Class<? extends Animal> clazz){
		Object obj = null;
		try {
			obj = Class.forName(clazz.getName()).newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return obj;
	}
}

package cn.jxliu.pattern.creational.factory;

public class Cat implements Animal {

	@Override
	public void eat() {
		System.out.println("Cat吃的方法!");
	}

}
package cn.jxliu.pattern.creational.factory;

public class Dog implements Animal {

	@Override
	public void eat() {
		System.out.println("Dog吃的方法!");
	}

}

package cn.jxliu.pattern.creational.factory;

public class Tiger implements Animal {

	@Override
	public void eat() {
		System.out.println("Tiger吃的方法!");
	}

}

package cn.jxliu.pattern.creational.factory;

public class FactoryPatternDemo {
	public static void main(String[] args) {
		AnimalFactory af = new AnimalFactory();
		Animal cat = af.getAnimal("Cat");
		cat.eat();
		Animal dog = af.getAnimal("Dog");
		dog.eat();
		Animal tiger = af.getAnimal("Tiger");
		tiger.eat();
		
		Cat c1 = (Cat)AnimalFactory.getClass(Cat.class);
		c1.eat();
	}
}


抽象工廠模式代碼:(紅色部分爲反射模式生成對象)


package cn.jxliu.pattern.creational.factory.abs;
/**
 * 動物接口
 * @author Administrator
 *
 */
public interface Animal {
	void eat();
}

package cn.jxliu.pattern.creational.factory.abs;


public interface Color {
	void fill();
}

package cn.jxliu.pattern.creational.factory.abs;


public class Cat implements Animal {


	@Override
	public void eat() {
		System.out.println("Cat吃的方法!");
	}


}

package cn.jxliu.pattern.creational.factory.abs;
/**
 * 繼承抽象工廠類,重新實現生成對象工廠的方法
 * @author Administrator
 *
 */
public class AnimalFactory extends AbstractFactory {

	@Override
	Animal getAnimal(String animalType) {
		if(animalType == null){
			return null;
		}
		if(animalType.equalsIgnoreCase("Cat")){
			return new Cat();
		}else if(animalType.equalsIgnoreCase("Dog")){
			return new Dog();
		}else if(animalType.equalsIgnoreCase("Tiger")){
			return new Tiger();
		}
		return null;
	}

	@Override
	Color getColor(String colorType) {
		return null;
	}

	/**
	 * 反射生成動物工廠
	 * @param clazz
	 * @return
	 */
	public static Object getAnimalFactory(Class<? extends Animal> clazz){
		Object obj = null;
		try {
			obj = Class.forName(clazz.getName()).newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return obj;
	}
}

package cn.jxliu.pattern.creational.factory.abs;

public class Black implements Color {

	@Override
	public void fill() {
		System.out.println("Black填充的方法!");
	}

}

package cn.jxliu.pattern.creational.factory.abs;

public class Cat implements Animal {

	@Override
	public void eat() {
		System.out.println("Cat吃的方法!");
	}

}

package cn.jxliu.pattern.creational.factory.abs;

public interface Color {
	void fill();
}

package cn.jxliu.pattern.creational.factory.abs;
/**
 * 繼承抽象工廠類,重新實現生成對象工廠的方法
 * @author Administrator
 *
 */
public class ColorFactory extends AbstractFactory {

	@Override
	Animal getAnimal(String animalType) {
		return null;
	}

	@Override
	Color getColor(String colorType) {
		if(colorType == null){
			return null;
		}
		if(colorType.equalsIgnoreCase("Green")){
			return new Green();
		}else if(colorType.equalsIgnoreCase("Red")){
			return new Red();
		}else if(colorType.equalsIgnoreCase("Black")){
			return new Black();
		}
		return null;
	}
	
	/**
	 * 通過工廠獲取對象
	 * @return
	 */
	public static Object getColorFactory(Class<? extends Color> clazz){
		Object obj = null;
		try {
			obj = Class.forName(clazz.getName()).newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return obj;
	}

}

package cn.jxliu.pattern.creational.factory.abs;

public class Dog implements Animal {

	@Override
	public void eat() {
		System.out.println("Dog吃的方法!");
	}

}

package cn.jxliu.pattern.creational.factory.abs;

public class FactoryProducer{
	public static AbstractFactory getFactory(String choice){
		if(choice.equalsIgnoreCase("AnimalFactory")){
			return new AnimalFactory();
		}else if(choice.equalsIgnoreCase("ColorFactory")){
			return new ColorFactory();
		}
		return null;
	}
	
	
	public static Object getAbstractFactory(Class<? extends AbstractFactory> clazz){
		Object obj = null;
		try {
			obj = Class.forName(clazz.getName()).newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return obj;
	}
}

package cn.jxliu.pattern.creational.factory.abs;

public class Green implements Color {

	@Override
	public void fill() {
		System.out.println("Green填充的方法!");
	}

}

package cn.jxliu.pattern.creational.factory.abs;

public class Red implements Color {

	@Override
	public void fill() {
		System.out.println("Red填充的方法!");
	}

}

package cn.jxliu.pattern.creational.factory.abs;

public class Tiger implements Animal {

	@Override
	public void eat() {
		System.out.println("Tiger吃的方法!");
	}

}

單例模式主要分懶漢式和餓漢式兩種,單例模式的誕生是用於保證一個類只能有一個對象,具體做法大概爲以下三點:一,創建對象的方式私有化;二,構造函數私有化;三,對外類提供一個獲取本類對象的方法。

單例模式代碼:

package cn.jxliu.pattern.creational.singleton;
/**
 * 懶漢式單例模式
 * 最大的缺點就是不支持多線程,因爲沒有加鎖synchronized
 * @author Administrator
 *
 */
public class LazySingleton {
	private static LazySingleton single;
	private LazySingleton(){}
	
	public static LazySingleton getInstance(){
		if(single == null){
			single = new LazySingleton();
		}
		return single;
	}
	
	public void eat(){
		System.out.println("吃吃次!");
	}
}
package cn.jxliu.pattern.creational.singleton;
/**
 * 餓漢式單例模式
 * 支持多線程,但容易產生垃圾對象
 * 優點:沒有加鎖,執行效率高
 * 缺點:類加載時就初始化,浪費內存
 * @author Administrator
 *
 */
public class HungrySingleton {
	private static HungrySingleton singleton = new HungrySingleton();
	private HungrySingleton(){}
	
	public static HungrySingleton getInstance(){
		return singleton;
	}
	
	public void run(){
		System.out.println("跑跑跑!");
	}
}

package cn.jxliu.pattern.creational.singleton;
/**
 * 雙檢鎖/雙重校驗鎖
 * 開局初始化,多線程安全,這種採用雙鎖機制的單例模式,安全,且在多線程下能保持高性能
 * @author Administrator
 *
 */
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 Singleton();
				}
			}
		}
		return singleton;
	}
}


package cn.jxliu.pattern.creational.singleton;
/**
 * 登記式單例類
 * 這種方式相對比餓漢式,優點在於只有在顯示調用getInstance時,纔會初始化singleton,同時支持多線程,實現也比較簡單
 * @author Administrator
 */
public class RegisterSingleton {
	private static class SingletonHolder{
		private static final RegisterSingleton INSTANCE = new RegisterSingleton();
	}
	
	private RegisterSingleton(){}
	/**
	 * 只有在顯示調用RegisterSingleton時,纔會初始化實例
	 * @return
	 */
	public static final RegisterSingleton getInstance(){
		return SingletonHolder.INSTANCE;
	}
	
}


建造者模式主要用於生成的對象之間具有複雜的內部結構並且對象內部屬性本身相互依賴,與工廠模式的區別是:建造者模式更加關注與零件裝配的順序。

建造者模式代碼:

package cn.jxliu.pattern.creational.builder;
/**
 * 相當於一件商品
 * @author Administrator
 *
 */
public interface Item {
	/**
	 * 名稱的功能
	 * @return
	 */
	public String name(); 
	/**
	 * 價格的功能
	 * @return
	 */
	public Float price();
	/**
	 * 打包的功能
	 * @return
	 */
	public Packing packing();
	
}

package cn.jxliu.pattern.creational.builder;
/**
 * 用於打包
 * @author Administrator
 *
 */
public interface Packing {
	public String pack();
}
package cn.jxliu.pattern.creational.builder;

public abstract class Burger implements Item {

	@Override
	public abstract Float price();
	
	/**
	 * 默認有了打包的功能
	 */
	@Override
	public Packing packing() {
		return new PaperPack();
	}

}
package cn.jxliu.pattern.creational.builder;

public abstract class Drink implements Item {

	@Override
	public abstract Float price();

	/**
	 * 默認自帶打包功能
	 */
	@Override
	public Packing packing() {
		return new BottlePack();
	}
	
}

package cn.jxliu.pattern.creational.builder;

public class HotBurger extends Burger {

	@Override
	public String name() {
		return "一個辣堡!";
	}

	@Override
	public Float price() {
		return 3.5f;
	}

}

package cn.jxliu.pattern.creational.builder;

public class SweetBurger extends Burger {

	@Override
	public String name() {
		return "一個甜堡!";
	}

	@Override
	public Float price() {
		return 5.5f;
	}

}

package cn.jxliu.pattern.creational.builder;

public class CokeDrink extends Drink{

	@Override
	public String name() {
		return "一杯咖啡!";
	}

	@Override
	public Float price() {
		return 6.8f;
	}
	
}

package cn.jxliu.pattern.creational.builder;

public class TeaDrink extends Drink {

	@Override
	public String name() {
		return "一杯茶!";
	}

	@Override
	public Float price() {
		return 10.05f;
	}

}
package cn.jxliu.pattern.creational.builder;
/**
 * 使用紙杯包裝
 * @author Administrator
 *
 */
public class PaperPack implements Packing{

	@Override
	public String pack() {
		return "使用紙杯包裝!";
	}

}
package cn.jxliu.pattern.creational.builder;
/**
 * 用杯包裝
 * @author Administrator
 *
 */
public class BottlePack implements Packing{

	@Override
	public String pack() {
		return "使用杯包裝!";
	}

}
package cn.jxliu.pattern.creational.builder;

import java.util.ArrayList;
import java.util.List;

public class Meal {
	private List<Item> items = new ArrayList<Item>();
	
	/**
	 * 添加商品的功能
	 * @param item
	 */
	public void addItem(Item item){
		items.add(item);
	}
	
	/**
	 * 計算價格
	 * @return
	 */
	public Float calculate(){
		float f = 0.0f;
		for (Item item : items) {
			f += item.price();
		}
		return f;
	}
	
	/**
	 * 展示商品
	 */
	public void showItems(){
		for (Item item : items) {
	         System.out.print("Item : "+item.name());
	         System.out.print(", Packing : "+item.packing().pack());
	         System.out.println(", Price : "+item.price());
	     }   
	}
}
package cn.jxliu.pattern.creational.builder;

public class MealFactory {
	public static Object getInstance(Class<? extends Meal> clazz){
		Object obj = null;
		try {
			obj = Class.forName(clazz.getName()).newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return obj;
	}
}
package cn.jxliu.pattern.creational.builder;

public class BuilderPatternDemo {
	public static void main(String[] args) {
		Meal m1 = (Meal)MealFactory.getInstance(Meal.class);
		m1.addItem(new HotBurger());
		m1.addItem(new CokeDrink());
		m1.showItems();
		System.out.println("總價爲:"+m1.calculate());
		
		Meal m2 = (Meal)MealFactory.getInstance(Meal.class);
		m2.addItem(new SweetBurger());
		m2.addItem(new TeaDrink());
		m2.showItems();
		m2.calculate();
		System.out.println("總價爲:"+m2.calculate());
	}
}








發佈了37 篇原創文章 · 獲贊 21 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章