1. 程式人生 > >白話設計模式--構造者模式和原型模式

白話設計模式--構造者模式和原型模式

設計模式是什麼?

設計模式,顧名思義,就是軟體設計過程中常見問題的解決方案,是經驗的總結。

設計模式型別:

一、Builder,構造者模式。它是構造複雜物件的一種方式,尤其是在用相同的方式構造不同物件時,顯得尤為有效。

例如,一般在封裝實體類時我們通常會用構造方法等形式往實體類傳遞引數,有可能對不同個數的引數進行初始化,你會定義出不同的構造方法,當然這都沒問題,如果是當前實體類中的引數過於多時,這時候再用構造方法傳遞引數會有點力不從心,很大程度上會影響程式碼的可讀性與美觀性。那這個時候構造者模式的出現完美的解決這一問題。

public class User
{
    private String firstName; // required
    private String lastName; // required
    private int age; // optional
    private String phone; // optional
    private String address; // optional
 
    private User(UserBuilder builder) {
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.age = builder.age;
        this.phone = builder.phone;
        this.address = builder.address;
    }
 
    //All getter, and NO setter to provde immutability
    public String getFirstName() {
        return firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public int getAge() {
        return age;
    }
    public String getPhone() {
        return phone;
    }
    public String getAddress() {
        return address;
    }
 
    @Override
    public String toString() {
        return "User: "+this.firstName+", "+this.lastName+", "+this.age+", "+this.phone+", "+this.address;
    }
 
    public static class UserBuilder
    {
        private final String firstName;
        private final String lastName;
        private int age;
        private String phone;
        private String address;
 
        public UserBuilder(String firstName, String lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        }
        public UserBuilder age(int age) {
            this.age = age;
            return this;
        }
        public UserBuilder phone(String phone) {
            this.phone = phone;
            return this;
        }
        public UserBuilder address(String address) {
            this.address = address;
            return this;
        }
        //Return the finally consrcuted User object
        public User build() {
            User user =  new User(this);
            validateUserObject(user);
            return user;
        }
        private void validateUserObject(User user) {
            //Do some basic validations to check
            //if user object does not break any assumption of system
        }
    }
}

構造物件:

public static void main(String[] args) {
    User user1 = new User.UserBuilder("Lokesh", "Gupta")
    .age(30)
    .phone("1234567")
    .address("Fake address 1234")
    .build();
 
    System.out.println(user1);
 
    User user2 = new User.UserBuilder("Jack", "Reacher")
    .age(40)
    .phone("5655")
    //no address
    .build();
 
    System.out.println(user2);
 
    User user3 = new User.UserBuilder("Super", "Man")
    //No age
    //No phone
    //no address
    .build();
 
    System.out.println(user3);
}
 
Output:
 
User: Lokesh, Gupta, 30, 1234567, Fake address 1234
User: Jack, Reacher, 40, 5655, null
User: Super, Man, 0, null, null

二、prototype,原型模式

原型是實際物件建立前的任何物件的模板,當你要建立一個物件的多個例項,而這些例項又幾乎相同或者說差別很小時,就可以使用原型模式。該模式的思想就是將一個物件作為原型,對其進行復制、克隆,產生一個和原物件類似的新物件。

示例:一個原型類,只需要實現Cloneable介面,覆寫clone方法

package com.howtodoinjava.prototypeDemo.contract;
 
public interface PrototypeCapable extends Cloneable
{
    public PrototypeCapable clone() throws CloneNotSupportedException;
}
package com.howtodoinjava.prototypeDemo.model;
 
import com.howtodoinjava.prototypeDemo.contract.PrototypeCapable;
 
public class Movie implements PrototypeCapable
{
    private String name = null;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public Movie clone() throws CloneNotSupportedException {
        System.out.println("Cloning Movie object..");
        return (Movie) super.clone();
    }
    @Override
    public String toString() {
        return "Movie";
    }
}
package com.howtodoinjava.prototypeDemo.factory;
 
import com.howtodoinjava.prototypeDemo.contract.PrototypeCapable;
import com.howtodoinjava.prototypeDemo.model.Movie;
 
public class PrototypeFactory
{
    public static class ModelType
    {
        public static final String MOVIE = "movie";
    }
    private static java.util.Map<String , PrototypeCapable> prototypes = new java.util.HashMap<String , PrototypeCapable>();
 
    static
    {
        prototypes.put(ModelType.MOVIE, new Movie());
    }
 
    public static PrototypeCapable getInstance(final String s) throws CloneNotSupportedException {
        return ((PrototypeCapable) prototypes.get(s)).clone();
    }
}
package com.howtodoinjava.prototypeDemo.client;
 
import com.howtodoinjava.prototypeDemo.factory.PrototypeFactory;
import com.howtodoinjava.prototypeDemo.factory.PrototypeFactory.ModelType;
 
public class TestPrototypePattern
{
    public static void main(String[] args)
    {
        try
        {
            String moviePrototype  = PrototypeFactory.getInstance(ModelType.MOVIE).toString();
            System.out.println(moviePrototype);
 
        }
        catch (CloneNotSupportedException e)
        {
            e.printStackTrace();
        }
    }
}

程式輸出:

Cloning Movie object..
Movie