創(chuàng)建型模式
Factory--工廠模式
簡單工廠模式
創(chuàng)建工廠對象,然后通過條件獲取相應(yīng)的對象,這種方式健壯性差,如果輸入的條件字符串不符合要求則不能獲取到相應(yīng)的對象。
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 {
// 條件都不符合,創(chuàng)建默認(rèn)對象
return new Dog();
}
}
}
public class FactoryModel {
public static void main(String[] args) {
PetFactory petFactory = new PetFactory();
Pet dog = petFactory.getPet("Dog");
dog.eat();
}
}
對普通工廠方法模式的改進(jìn),在普通工廠方法模式中,如果傳遞的字符串出錯(cuò),則不能正確創(chuàng)建對象,提供多個(gè)工廠方法,分別創(chuàng)建對象。
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();
}
}
多個(gè)工廠方法模式
有時(shí)需要新增一個(gè)或多個(gè)種類,例如新加一個(gè)Bird動(dòng)物,可實(shí)現(xiàn)動(dòng)物接口,以及實(shí)現(xiàn)工廠類,這樣就不需要去修改其他的接口了。
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--抽象工廠模式
抽象工廠模式中彌補(bǔ)了工廠模式的不足(一個(gè)工廠只能生產(chǎn)一種產(chǎn)品)。工廠模式中一個(gè)工廠只能生產(chǎn)一種產(chǎn)品,而抽象工廠可以生產(chǎn)多個(gè)。
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--單例模式
單例對象能保證在一個(gè)JVM中,該對象只有一個(gè)實(shí)例存在。
餓漢模式
直接創(chuàng)建該對象,不是懶加載。
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();
}
}
懶漢模式
只有需要用到該對象才創(chuàng)建。使用雙重檢查鎖機(jī)制。在還沒有該對象的時(shí)候,第一次判斷為空,此時(shí)可能會(huì)有多個(gè)線程進(jìn)入到這,也就是說多個(gè)線程都判斷為空成立,此時(shí)某個(gè)線程獲得鎖資源,待該線程釋放鎖,會(huì)有下一個(gè)線程獲得鎖資源,如果不再次判斷是否為空,則之后的線程會(huì)再次創(chuàng)建對象,此時(shí)第一個(gè)獲得鎖資源的線程已經(jīng)創(chuàng)建了對象,則再次判斷可以避免再次創(chuàng)建對象。
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--建造者模式
將一個(gè)復(fù)雜對象的構(gòu)建與它的屬性分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的屬性。
目的是將構(gòu)建復(fù)雜對象的過程和它的屬性解耦。
類比房子,房子是個(gè)對象,而屋頂和地基都是房子的屬性,而建造屋頂和地基都有單獨(dú)的方法實(shí)現(xiàn)。
工廠模式關(guān)注的是創(chuàng)建單個(gè)產(chǎn)品,而建造者模式則關(guān)注創(chuàng)建復(fù)雜的對象,包含多個(gè)部分。
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--原型模式
定義:用原型實(shí)例通過拷貝創(chuàng)建新的對象。Prototype模式允許一個(gè)對象再創(chuàng)建另外一個(gè)可定制的對象,根部無需知道任何創(chuàng)建的細(xì)節(jié),工作原理:通過將一個(gè)原型對象傳給創(chuàng)建方法,從而通過對原型對象的拷貝來創(chuàng)建新的對象。
淺復(fù)制
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();
}
}
}
深復(fù)制
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 {
// 創(chuàng)建一個(gè)字節(jié)數(shù)組輸出流用來保存序列化后對象的字節(jié)
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 創(chuàng)建一個(gè)對象輸出流
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
// 將對象寫出到之前創(chuàng)建的字節(jié)輸出流中
objectOutputStream.writeObject(this);
// 將字節(jié)數(shù)組輸出流轉(zhuǎn)化為字節(jié)數(shù)組
byte[] bytes = byteArrayOutputStream.toByteArray();
// 創(chuàng)建一個(gè)字節(jié)輸入流,將上面的對象字節(jié)寫入到流中
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
// 創(chuàng)建一個(gè)對象輸入流,將字節(jié)輸入流包裝
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
// 從流中將對象寫出來,強(qiáng)轉(zhuǎn)為該對象類型
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());
}
}
結(jié)構(gòu)型模式
Adapter--適配器模式
類適配器
通過繼承來實(shí)現(xiàn)適配器功能
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();
}
}
對象適配器
通過對象實(shí)例來實(shí)現(xiàn)適配器功能
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();
}
}
接口適配器
如果需要定義一個(gè)類,且只需要接口中部分方法,可以使用抽象類去實(shí)現(xiàn)接口,然后使用該類去繼承抽象類,就可以去重寫部分方法了。
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--橋接模式
橋接模式就是把事物和其具體實(shí)現(xiàn)分開,使他們可以各自獨(dú)立的變化。像常用的JDBC橋DriverManager一樣,JDBC進(jìn)行連接數(shù)據(jù)庫的時(shí)候,在各個(gè)數(shù)據(jù)庫之間進(jìn)行切換。
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--組合模式
將對象以樹形組織起來,以達(dá)成“部分-整體”的層次結(jié)構(gòu),使得客戶端對單個(gè)對象 和組合對象的使用具有一致性。