天天看點

HeadFirst設計模式

設計原則一:把會變化的部分取出并“封裝”起來,好讓其他部分不受影響。

設計原則二:針對接口程式設計而不是針對實作程式設計。

針對實作程式設計就必須進行具體實作,針對接口程式設計,就可以對接口進行多态的調用

實作Animal接口,并建立所有的空方法。

實作Dog類,Cat類,實作具體的類

Animal animal = new Dog();
Animal animal = new Cat();

animal.bark()           

複制

這就會在運作時實作相應的方法

FlyBehavior 和 QuackBehavior 是飛和叫行為的接口

針對接口實作具體的飛行和叫的類

整合
public Duck(){
    QuackBehavior quackBehavior;
    public void performQuack(){
        quackBehavior.quack();
    }
}           

複制

抽象父類隻負責實作相應功能不用管具體是哪一個實作。

子類想調用哪一個行為,就new一個新的行為。

public class MallardDuck extends Duck{
    
    public MallardDuck(){
        quackBehavior = new Quack();
        flyBehavior = new FlyWithWings();
    }
}           

複制

public interface FlyBehavior {
    void doFly();
}
public interface QuackBehavior {
    void doQuack();
}
public class FlyNoWings implements FlyBehavior {
    @Override
    public void doFly() {
        System.out.println("隻能飛過牆頭");
    }
}
public class FlyWithWings implements FlyBehavior {
    @Override
    public void doFly() {
        System.out.println("實作高度800米的飛翔");
    }
}
public class QuackMute implements QuackBehavior {
    @Override
    public void doQuack() {
        System.out.println("輕輕的叫");
    }
}
public class SQuack implements QuackBehavior {
    @Override
    public void doQuack() {
        System.out.println("呱呱的叫");
    }
}
abstract  public class Duck {

    FlyBehavior flyBehavior;
    QuackBehavior quackBehavior;


    public void performFly(){
        flyBehavior.doFly();
    }

    public void performQuack(){
        quackBehavior.doQuack();
    }

    public void setFlyBehavior(FlyBehavior flyBehavior){
        this.flyBehavior = flyBehavior;
    }

    public  void setQuackBehavior(QuackBehavior quackBehavior){
        this.quackBehavior = quackBehavior;
    }
}
public class SmallDuck extends Duck {

}
public class Main {

    public static void main(String[] args) {
        SmallDuck smallDuck = new SmallDuck();
        smallDuck.setFlyBehavior(new FlyNoWings());
        smallDuck.setQuackBehavior(new QuackMute());
        smallDuck.performFly();
        smallDuck.performQuack();
    }
}           

複制

觀察者模式

出版者 + 訂閱者 = 觀察者模式

設計原則三:為了互動對象之間的松耦合而設計

/***
 *  主題需要提供注冊,删除,全局通知接口
 */
public interface Subject {

    public void registerObserver(Observer o);
    public void removeRegister(Observer o);
    public void notifyObservers();
}

/***
 * 觀察者接口需要提供觀察者接受消息更新的統一接口
 */
public interface Observer {
    public void update(int temp,int humidity,int pressure);
}

/***
 * 展示子產品,需要提供展示的統一接口
 */
public interface DisplayElement {
    public void display();
}

public class WeatherData implements Subject {

    private List<Observer> observerList = null;
    private int temp;
    private int humidity;
    private int pressure;

    public WeatherData(){
        observerList = new ArrayList<Observer>();
    }

    @Override
    public void registerObserver(Observer o) {
        observerList.add(o);
    }

    @Override
    public void removeRegister(Observer o) {
        int index = observerList.indexOf(o);
        observerList.remove(index);
    }

    @Override
    public void notifyObservers() {
        for (Observer it: observerList) {
            it.update(temp,humidity,pressure);
        }
    }

    public void measureChanged(){
        notifyObservers();
    }

    public void setMeasure(int temp,int humidity,int pressure){
        this.temp = temp;
        this.humidity = humidity;
        this.pressure = pressure;
        measureChanged();
    }
}

public class ForecastDisplay implements Observer, DisplayElement {

    private int temp;
    private int pressure;
    private Subject weatherData;

    public ForecastDisplay(Subject weatherData){
        this.weatherData = weatherData;
        weatherData.registerObserver(this);
    }
    @Override
    public void display() {
        System.out.println("temp is " + temp + " pressure" + pressure + " weatherData" + weatherData);
    }

    @Override
    public void update(int temp, int humidity, int pressure) {
         this.temp = temp;
         this.pressure = pressure;
         display();
    }
}

public class CurrentDisplay implements Observer, DisplayElement {

    private int temp;
    private int humidity;
    private Subject weatherData;

    public CurrentDisplay(Subject weatherData){
        this.weatherData = weatherData;
        weatherData.registerObserver(this);
    }

    @Override
    public void display() {
        System.out.println("Current conditions: " + temp + "F degrees and "+ humidity + "% humidity");
    }

    @Override
    public void update(int temp, int humidity, int pressure) {
        this.temp = temp;
        this.humidity = humidity;
        this.display();
    }

}

 public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();
        CurrentDisplay currentDisplay = new CurrentDisplay(weatherData);
        ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);

        weatherData.setMeasure(15,16,19);
    }           

複制

多用組合,少用繼承。

觀察者模式-在對象間定義一個一對多的依賴,這樣。主題用一個 共同的接口更新觀察者。

Swing ,JavaBeans,RMI,大量使用觀察者模式。

裝飾者模式

設計原則四,類應該對擴充開放,對修改關閉。

裝飾者動态的将責任附加到對象上,若要擴充功能,裝飾者比繼承更有彈性替代方案。

public abstract class Beverage {

    String description = "Unkown Beverage";

    public String getDescription(){
        return  description;
    }
    public abstract double cost();
}

public  abstract  class CondimentDecorator extends  Beverage {
    public abstract String getDescription();
}

public class DarkRoast extends CondimentDecorator {
    Beverage beverage;

    public DarkRoast(Beverage beverage){
        this.beverage = beverage;
    }
    @Override
    public String getDescription() {
        return beverage.getDescription() + ", DarkRoast";
    }

    @Override
    public double cost() {
        return beverage.cost() + 0.36;
    }
}

public class Espresso extends Beverage {

    public Espresso(){
        description = "Espresso";
    }
    @Override
    public double cost() {
        return 1.99;
    }
}
public class HouseBlend extends Beverage {

    public HouseBlend(){
        description = "HouseBlend";
    }

    @Override
    public double cost() {
        return 0.89;
    }
}

public class Mocha extends CondimentDecorator {
    Beverage beverage;

    public Mocha(Beverage beverage){
        this.beverage = beverage;
    }
    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Mocha";
    }

    @Override
    public double cost() {
        return beverage.cost() + .20;
    }
}

 public static void main(String[] args) {
        Beverage beverage = new Espresso();
        Beverage beverage1 = new HouseBlend();

        Beverage sum = new Mocha(beverage);
        System.out.println(sum.getDescription());
        Beverage sum1 = new DarkRoast(sum);
        System.out.println(sum1.getDescription() + sum1.cost());
}           

複制

java I/O中有大量裝飾器的實作代碼,InputStream,FileInputStream,StringBufferInputStream

裝飾器是除了繼承外的另一種擴充方式。

裝飾器可以在被裝飾者的行為面前加上自己的行為,甚至被裝飾者整個行為被去掉。

工廠模式

工廠方法模式定義了一個建立對象的接口,但由子類決定要執行個體化的類是哪一個,工廠方法讓類把執行個體化推遲到子類。

設計原則五,要依賴抽象,不要依賴具體類。

/**
 * 建立接口
 */
public interface Shape {
     void draw();
}
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("draw a Circle ~~");
    }
}
public class Rectangle implements Shape {

    @Override
    public void draw() {
        System.out.println("draw a new Rectangle ~~~");
    }
}
public class ShapeFactory {

    public Shape getShape(String shapeType){
        if(shapeType==null){
            return null;
        }
        if(shapeType.equalsIgnoreCase("CIRCLE")){
            return  new Circle();
        }else if(shapeType.equalsIgnoreCase("RECTANGLE")){
            return  new Rectangle();
        }

        return null;
    }
}
public class Main {

    public static void main(String[] args) {
        ShapeFactory shapeFactory = new ShapeFactory();

        //擷取circle
        Shape shape1 = shapeFactory.getShape("CIRCLE");
        Shape shape2 = shapeFactory.getShape("RECTANGLE");
        shape1.draw();
        shape2.draw();
    }
}           

複制

單例模式

有些對象我們隻需要一個:線程池,緩存,對話框等等。

含有私有構造器的類不能被執行個體化

public class Singleton {
    private static Singleton uniqueInstance;
    private Singleton(){}
    public static Singleton getInstance(){
        if(uniqueInstance==null){
            return new Singleton();
        }else{
            return uniqueInstance;
        }
    }
}           

複制

指令模式

實作指令接口,讓所有指令對象實作包含相同方法的接口。

指令模式,就是将實體類的方法的執行進行封裝

  • 實作統一的方法執行接口,對每一個方法的執行實作一個類的封裝
  • 實作 對Command的傳入,執行
class Light{
    public void on {
        print("light is on")
    }
    public void off {
        print("light is off")
    }
}           

複制

public interface Command {
    public void execute();
}           

複制

public class LightOnCommand implements Command{
    Light light;
    public LightOnCommand(Light light){
        this.light = light
    }
    
    public void execute(){
        light.on()
    }
}           

複制

實作接口的傳入,與執行這樣和底層進行分開,實作的單獨的指令執行

public class SimpleRemoteControl{
    Command solt;
    
    public SimpleRemoteControl(){}
    public void setCommand(Command command){
        slot = command;
    }
    public void buttonWasPassed(){
        slot.execute();
    }
}           

複制

擴充卡模型

擴充卡,相當于兩個類的對接接口

A 強轉 B 擴充卡的實作是建立一個類,實作B接口,同時通過構造函數傳參A,在實作的B的方法中執行A方法。

B接口與實作類

public interface Duck{
    public void quick();
    public void fly();
}           

複制

public class MallarDuck implements Duck{

   public void quick(){
       print("Quick")
   }
   public void fly(){
       print("fly")
   }
}           

複制

A接口與實作類

public interface Turkey{
    public void gobble();
    public void fly();
}           

複制

public class WildTurkey implements Turkey{
    public void gobble(){
        print("GOOBLE")
    }
    public void fly(){
        print("Fly")
    }
}           

複制

擴充卡

public TurkeyAdapter implements Duck{
    Turkey turkey;
    
    public TurkeyAdapter(Turkey turkey){
        this.turkey = turkey;
    }
    public void quack(){
        turkey.gobble();
    }
    public void fly(){
        turkey.fly()
    }
}           

複制

模闆模式

模闆方法把一類的操作給單獨抽出來

public abstract class CaffeineBeverageWithHook {

    //提出公共的方法流程
    void prepareRecipe(){
        boilWater();
        brew();
        pourInCup();
        if(customerWantsCondiments()){
            addCondiments();
        }
    }

    //不同飲料,最大的不同點,可以抽象化
    abstract  void  brew();

    abstract  void  addCondiments();

    void boilWater(){
        System.out.println("boiling water");
    }

    void pourInCup(){
        System.out.println("pouring into cup");
    }

    boolean customerWantsCondiments(){
        return true;
    }
}           

複制

public class CoffeeWithHook extends  CaffeineBeverageWithHook {
    @Override
    void brew() {
        System.out.println("Dripping Coffee through filter");
    }

    @Override
    void addCondiments() {
        System.out.println("Adding Suger and Milk");
    }

    public  boolean customerWantsCondiments(){
        String answer = getUserInput();

        if(answer.startsWith("y")){
            return true;
        }else{
            return  false;
        }
    }

    private String getUserInput(){
        String answer = null;
        System.out.println("Would you like milk and sugar with your coffee (y/n)");
        return  answer;
    }
}           

複制

疊代器模式

public interface Iterator{

    boolean hasNext();

    Object next();
}           

複制

public class MenuItem {

    String name;
    String description;
    boolean vegetarian;
    double  price;

    public MenuItem(String name,String description,boolean vegetarian,double price){
        this.name = name;
        this.description = description;
        this.vegetarian = vegetarian;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public boolean isVegetarian() {
        return vegetarian;
    }

    public void setVegetarian(boolean vegetarian) {
        this.vegetarian = vegetarian;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}           

複制

/**
 * 針對接口程式設計,對于每一個數組或者集合實作Iterator ,這樣對于數組和清單的周遊
 * 在程式底層隻用實作對Iterator的周遊
 */
public class DinerMenuIterator implements Iterator {
    MenuItem[] items;
    int position = 0;

    public  DinerMenuIterator(MenuItem[] items){
        this.items = items;
    }
    @Override
    public boolean hasNext() {
        if(position>=items.length || items[position] == null){
            return false;
        }else {
            return true;
        }
    }

    @Override
    public Object next() {
        MenuItem menuItem = items[position];
        position = position + 1;
        return menuItem;
    }
}           

複制

public class PanCakeMenuIterator implements Iterator {
    ArrayList<MenuItem> items;
    int position = 0;

    public PanCakeMenuIterator(ArrayList<MenuItem> items){
        this.items = items;
    }

    @Override
    public boolean hasNext() {
        if(position == items.size() || items.get(position) ==null){
            return false;
        }else {
            return true;
        }
    }

    @Override
    public Object next() {
        MenuItem item = items.get(position);
        position = position + 1;
        return item;
    }
}           

複制