創建型模式
Factory--工廠模式
簡單工廠模式
創建工廠對象,然后通過條件獲取相應的對象,這種方式健壯性差,如果輸入的條件字符串不符合要求則不能獲取到相應的對象。
interface Pet {
public void eat();
}
class Dog implements Pet {
@Override
public void eat() {
System.out.print("Dog is eat");
}
}
class Cat implements Pet {
@Override
public void eat() {
System.out.print("Cat is eat");
}
}
class PetFactory {
public Pet getPet(String name) {
if(name.equals("Dog")) {
return new Dog();
}else if (name.equals("Cat")) {
return new Cat();
}else {
// 條件都不符合,創建默認對象
return new Dog();
}
}
}
public class FactoryModel {
public static void main(String[] args) {
PetFactory petFactory = new PetFactory();
Pet dog = petFactory.getPet("Dog");
dog.eat();
}
}
對普通工廠方法模式的改進,在普通工廠方法模式中,如果傳遞的字符串出錯,則不能正確創建對象,提供多個工廠方法,分別創建對象。
interface Pet {
public void eat();
}
class Dog implements Pet {
@Override
public void eat() {
System.out.print("Dog is eat");
}
}
class Cat implements Pet {
@Override
public void eat() {
System.out.print("Cat is eat");
}
}
class PetFactory {
public Pet getDog() {
return new Dog();
}
public Pet getCat() {
return new Cat();
}
}
public class FactoryModel {
public static void main(String[] args) {
PetFactory petFactory = new PetFactory();
Pet dog = petFactory.getDog();
dog.eat();
}
}
多個工廠方法模式
有時需要新增一個或多個種類,例如新加一個Bird動物,可實現動物接口,以及實現工廠類,這樣就不需要去修改其他的接口了。
interface Pet {
public void eat();
}
class Dog implements Pet {
@Override
public void eat() {
System.out.print("Dog is eat");
}
}
class Cat implements Pet {
@Override
public void eat() {
System.out.print("Cat is eat");
}
}
interface Factory {
public Pet produce();
}
class DogFactory implements Factory {
@Override
public Pet produce() {
return new Dog();
}
}
class CatFactory implements Factory {
@Override
public Pet produce() {
return new Cat();
}
}
public class AbstractFactoryModel {
public static void main(String[] args) {
Factory factory = new DogFactory();
Pet dog = factory.produce();
dog.eat();
}
}
AbstractFactory--抽象工廠模式
抽象工廠模式中彌補了工廠模式的不足(一個工廠只能生產一種產品)。工廠模式中一個工廠只能生產一種產品,而抽象工廠可以生產多個。
package AbstractFactoryModel;
interface Pet {
public void eat();
}
interface Dog extends Pet {
}
interface Cat extends Pet{
}
class ChinaDog implements Dog {
@Override
public void eat() {
System.out.println("China dog is eat...");
}
}
class ForeignDog implements Cat {
@Override
public void eat() {
System.out.println("Foreign dog is eat...");
}
}
class ChinaCat implements Cat {
@Override
public void eat() {
System.out.println("China cat is eat...");
}
}
class ForeignCat implements Cat {
@Override
public void eat() {
System.out.println("Foreign cat is eat...");
}
}
interface PetFactory {
public Pet produceDog();
public Pet produceCat();
}
class ChinaFactory implements PetFactory {
@Override
public Pet produceDog() {
return new ChinaDog();
}
@Override
public Pet produceCat() {
return new ChinaCat();
}
}
class ForeignFactory implements PetFactory {
@Override
public Pet produceDog() {
return new ForeignDog();
}
@Override
public Pet produceCat() {
return new ForeignCat();
}
}
public class AbstractFactoryModel {
public static void main(String[] args) {
PetFactory chinaFactory = new ChinaFactory();
Pet dog = chinaFactory.produceDog();
dog.eat();
}
}
Singleton--單例模式
單例對象能保證在一個JVM中,該對象只有一個實例存在。
餓漢模式
直接創建該對象,不是懶加載。
class SingletonModel {
private static SingletonModel singleton = new SingletonModel();
private SingletonModel() {
}
public static SingletonModel getInstance() {
return singleton;
}
}
public class HungarySingletonModel {
public static void main(String[] args) {
SingletonModel instance = SingletonModel.getInstance();
}
}
懶漢模式
只有需要用到該對象才創建。使用雙重檢查鎖機制。在還沒有該對象的時候,第一次判斷為空,此時可能會有多個線程進入到這,也就是說多個線程都判斷為空成立,此時某個線程獲得鎖資源,待該線程釋放鎖,會有下一個線程獲得鎖資源,如果不再次判斷是否為空,則之后的線程會再次創建對象,此時第一個獲得鎖資源的線程已經創建了對象,則再次判斷可以避免再次創建對象。
class SingletonModel {
private static SingletonModel singleton = null;
private SingletonModel() {
}
public static SingletonModel getInstance() {
if (singleton == null) {
synchronized (singleton) {
if (singleton == null) {
singleton = new SingletonModel();
}
}
}
return singleton;
}
}
public class LazySingletonModel {
public static void main(String[] args) {
SingletonModel instance = SingletonModel.getInstance();
}
}
Builder--建造者模式
將一個復雜對象的構建與它的屬性分離,使得同樣的構建過程可以創建不同的屬性。
目的是將構建復雜對象的過程和它的屬性解耦。
類比房子,房子是個對象,而屋頂和地基都是房子的屬性,而建造屋頂和地基都有單獨的方法實現。
工廠模式關注的是創建單個產品,而建造者模式則關注創建復雜的對象,包含多個部分。
class House {
private String roof;
private String foundation;
public String getRoof() {
return roof;
}
public void setRoof(String roof) {
this.roof = roof;
}
public String getFoundation() {
return foundation;
}
public void setFoundation(String foundation) {
this.foundation = foundation;
}
}
interface Builder {
void buildRoof();
void buildFoundation();
House createHouse();
}
class HouseBuilder implements Builder {
private House house;
public HouseBuilder(House house) {
this.house = house;
}
@Override
public void buildRoof() {
this.house.setRoof("roof");
}
@Override
public void buildFoundation() {
this.house.setFoundation("foundation");
}
@Override
public House createHouse() {
return this.house;
}
}
class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public House construct() {
builder.buildRoof();
builder.buildFoundation();
return builder.createHouse();
}
}
public class BuilderModel {
public static void main(String[] args) {
House house = new House();
Builder builder = new HouseBuilder(house);
Director director = new Director(builder);
house = director.construct();
System.out.println(house);
}
}
Prototype--原型模式
定義:用原型實例通過拷貝創建新的對象。Prototype模式允許一個對象再創建另外一個可定制的對象,根部無需知道任何創建的細節,工作原理:通過將一個原型對象傳給創建方法,從而通過對原型對象的拷貝來創建新的對象。
淺復制
class Pet implements Cloneable{
private String name;
private int age;
public Pet(String name, int age) {
this.name = name;
this.age = age;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class PrototypeModel {
public static void main(String[] args) {
Pet pet = new Pet("Tom", 1);
System.out.println("Pet'address is " + pet.toString());
try {
Pet clone_pet = (Pet) pet.clone();
System.out.println("Clone pet'address is " + clone_pet.toString());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
深復制
package PrototypeModel;
import java.io.*;
class Dog implements Serializable{
private String name;
private int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
public void introduce() {
System.out.println(this.name + "'age is " + this.age);
}
public Dog clone() {
try {
// 創建一個字節數組輸出流用來保存序列化后對象的字節
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 創建一個對象輸出流
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
// 將對象寫出到之前創建的字節輸出流中
objectOutputStream.writeObject(this);
// 將字節數組輸出流轉化為字節數組
byte[] bytes = byteArrayOutputStream.toByteArray();
// 創建一個字節輸入流,將上面的對象字節寫入到流中
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
// 創建一個對象輸入流,將字節輸入流包裝
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
// 從流中將對象寫出來,強轉為該對象類型
Dog dog = (Dog) objectInputStream.readObject();
return dog;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
public class DeepPrototypeModel {
public static void main(String[] args) {
Dog dog = new Dog("Tom", 2);
dog.introduce();
System.out.println(dog.toString());
Dog cloneDog = dog.clone();
cloneDog.introduce();
System.out.println(cloneDog.toString());
}
}
結構型模式
Adapter--適配器模式
類適配器
通過繼承來實現適配器功能
interface Usb {
void isUsb();
}
interface Ps2 {
void isPs2();
}
class Usber implements Usb {
@Override
public void isUsb() {
System.out.println("Usb接口");
}
}
class Adapter extends Usber implements Ps2 {
@Override
public void isPs2() {
System.out.println("Ps2接口");
}
}
public class ClassAdapter {
public static void main(String[] args) {
Adapter p = new Adapter();
p.isPs2();
p.isUsb();
}
}
對象適配器
通過對象實例來實現適配器功能
interface Usb {
void isUsb();
}
interface Ps2 {
void isPs2();
}
class Usber implements Usb {
@Override
public void isUsb() {
System.out.println("Usb接口");
}
}
class Adapter implements Ps2 {
private Usber usb;
public Adapter(Usber usb) {
this.usb = usb;
}
@Override
public void isPs2() {
System.out.println("Ps2接口");
}
public void isUsb() {
this.usb.isUsb();
}
}
public class ObjectAdapter {
public static void main(String[] args) {
Adapter adapter = new Adapter(new Usber());
adapter.isPs2();
adapter.isUsb();
}
}
接口適配器
如果需要定義一個類,且只需要接口中部分方法,可以使用抽象類去實現接口,然后使用該類去繼承抽象類,就可以去重寫部分方法了。
interface People {
void eat();
void run();
}
abstract class Adapter implements People {
@Override
public void eat() {
}
@Override
public void run() {
}
}
class Baby extends Adapter {
@Override
public void eat() {
System.out.println("I can eat!");
}
}
class InterfaceAdapterModel {
public static void main(String[] args) {
Baby baby = new Baby();
baby.eat();
}
}
Bridge--橋接模式
橋接模式就是把事物和其具體實現分開,使他們可以各自獨立的變化。像常用的JDBC橋DriverManager一樣,JDBC進行連接數據庫的時候,在各個數據庫之間進行切換。
interface JDBC {
void connect();
}
class mysql implements JDBC {
@Override
public void connect() {
System.out.println("connect mysql...");
}
}
class oracle implements JDBC {
@Override
public void connect() {
System.out.println("connect oracle...");
}
}
abstract class Bridge {
private JDBC jdbc;
public void connect() {
jdbc.connect();
}
public JDBC getJdbc() {
return jdbc;
}
public void setJdbc(JDBC jdbc) {
this.jdbc = jdbc;
}
}
class MyBridge extends Bridge {
@Override
public void connect() {
super.connect();
}
}
public class BridgeModel {
public static void main(String[] args) {
Bridge bridge = new MyBridge();
JDBC jdbc = new mysql();
bridge.setJdbc(jdbc);
bridge.connect();
JDBC oracle = new oracle();
bridge.setJdbc(oracle);
bridge.connect();
}
}
Composite--組合模式
將對象以樹形組織起來,以達成“部分-整體”的層次結構,使得客戶端對單個對象 和組合對象的使用具有一致性。