23種設計模式-----建立型模式、結構型模式

1、建立型模式(都是用來幫助建立對象的)

1.單例模式

  • 做用:保證一個類只有一個實例,而且提供一個訪問該實例的全局訪問點
  • 應用:Windows的任務管理器、回收站;項目中讀取配置文件的類;網站的計數器;應用程序的日誌應用;數據庫鏈接池;操做系統的文件系統;Application;Spring中的bean;Servlet;spring MVC框架/struts1框架中的控制器對象
  • 選用:佔用資源小、不須要延時加載--------枚舉-->餓漢           佔用資源大 、須要延時    --------------  靜態內部-->懶漢
  • 實現方式:

1.餓漢式(線程安全,調用效率高,不能延時加載)java

public class SingLetonDemo01 {
	
	//類初始化時,當即加載這個對象。加載類時,自然的線程安全
	private static SingLetonDemo01  sld = new SingLetonDemo01();
	
    //構造器私有化 private SingLetonDemo01() { } //方法沒有同步,調用效率高 public static SingLetonDemo01 getsld() { return sld; } }

2.懶漢式(線程安全,調用效率不高,能夠延時加載,併發效率低)spring

public class SingLetonDemo02 {
	
    //不初始化,臨時加載,使用時再加載 private static SingLetonDemo02 lsd; //構造器私有化 private SingLetonDemo02() { } //方法必須加入同步(有同步,效率低) public static synchronized SingLetonDemo02 getlsd() { if(lsd==null) { lsd = new SingLetonDemo02(); } return lsd; } }

3.雙重檢測鎖式(不安全,不建議使用)數據庫

4.靜態內部類式(線程安全,調用效率高,能夠延時加載,併發效率高)安全

public class SingLetonDemo03 {
	
	
	private static class SingLetonClassInstance{
		private static final SingLetonDemo03 sld = new SingLetonDemo03();
	}
	
	//私有構造器
	private SingLetonDemo03() {
	}
	
	//方法沒有同步
	public static SingLetonDemo03 getsld() {
		return SingLetonClassInstance.sld;
	}
}

5.枚舉單例(簡單,線程安全,調用效率高,不能延時加載)併發

public enum SingLetonDemo04 {
	
	//枚舉自己就是單例
	sld;
	
	//添加須要的操做
	public void singletonOperation() {
	}
}

2.工廠模式

實現了建立者和調用者的分離框架

實例化對象,用工廠方法代替new操做ide

將選擇實現類、建立對象統一管理和控制,從而將調用者跟實現類解耦單元測試

1.簡單工廠模式測試

  • 用來生產同一等級結構中任意產品(新增產品須要修改代碼)

方法一:網站

public class CarFactory01 {
    //建立者
    public static Car createcar(String type) {
        
        if("奧迪".equals(type)) {
            return new Audi();
        }else if("奔馳".equals(type)) {
            return new Benz();
        }else {
            return null;
        }  
    }
}

 

方法二:

public class CarFactory02 {
    //建立者
    public static Car createAudi() {
        return new Audi();
    }
    public static Car createBenz() {
        return new Benz();
    }
        
}

測試:

public class Client01 {
    //調用者
    public static void main(String[] args) {
        Car c1 = CarFactory01.createcar("奧迪");
        Car c2 = CarFactory01.createcar("奔馳");
        
        c1.run();
        c2.run();
    }
}

 

public class Client02 {
    //調用者
    public static void main(String[] args) {
        Car c1 = CarFactory02.createAudi();
        Car c2 = CarFactory02.createBenz();
        
        c1.run();
        c2.run();
    }
}

2.工廠方法模式

  • 用來生產同一等級固定產品(可新增任意產品)

汽車接口

 

public interface Car {
    void run();
}

汽車工廠接口

public interface CarFactory {
    Car createCar();
}

 

實現類

public class AudiFactory implements CarFactory{
    @Override
    public Car createCar() {
        return new Audi();
    }
}

 

測試

public class Client {
    public static void main(String[] args) {
        Car c1 = new AudiFactory().createCar();
        Car c2 = new BenzFactory().createCar();
        
        c1.run();
        c2.run();
    }
}

 

 

3.抽象工廠模式

用來生產不一樣產品族的所有產品(不能新增、支持新增產品族)

產品接口一:

 

public interface Engine {
    void run();
    void start();
}

class LuxuryEngine implements Engine{
    @Override
    public void run() {
        System.out.println("動力強");
    }
    
    @Override
    public void start() {
        System.out.println("啓動快");
    }
}

class LowEngine implements Engine{
    @Override
    public void run() {
        System.out.println("動力弱");
    }
    @Override
    public void start() {
        System.out.println("啓動慢");
    }
}

 

 

 

產品接口二:

 

public interface Seat {
    void massage();
}

class LuxurySeat implements Seat{
    @Override
    public void massage() {
        System.out.println("自動加熱");
    }
}
class LowSeat implements Seat{
    @Override
    public void massage() {
        System.out.println("無自動加熱");
    }
}

 

 

產品接口三:

public interface Tyre {
    void revolve();
}

class LuxuryTyre implements Tyre{
    @Override
    public void revolve() {
        System.out.println("磨損慢");
    }
}

class LowTyre implements Tyre{
    @Override
    public void revolve() {
        System.out.println("磨損快");
    }
}

 

汽車工廠接口:

 

public interface CarFactory {
    Engine createEngine();
    Seat   createSeat();
    Tyre   createTyre();
}
public class LuxuryCarFactory implements CarFactory{

    @Override
    public Engine createEngine() {
        return new LuxuryEngine();
    }

    @Override
    public Seat createSeat() {
        return new LuxurySeat();
    }

    @Override
    public Tyre createTyre() {
        return new LuxuryTyre();
    }

}

 

測試:

public class Client {
    public static void main(String[] args) {
        CarFactory factory = new LuxuryCarFactory();
        Engine  e = factory.createEngine();
        e.run();
        e.start();
    }
}

 

4.建造者模式

Builder負責構造、Director負責裝配   實現了構建和裝配的解耦。

不一樣的構建器,相同的裝配,能夠作出不一樣的對象

相同的構建,不一樣的裝配,也是不一樣的對象

汽車:

public class Car {
    private Engine engine;//發動機
    private Seat seat;//座椅
    private Tyre tyre;//輪胎
    
    public void run() {
        System.out.println("汽車發動");
    }
    
    public Engine getEngine() {
        return engine;
    }
    public void setEngine(Engine engine) {
        this.engine = engine;
    }
    public Seat getSeat() {
        return seat;
    }
    public void setSeat(Seat seat) {
        this.seat = seat;
    }
    public Tyre getTyre() {
        return tyre;
    }
    public void setTyre(Tyre tyre) {
        this.tyre = tyre;
    }
}

class Engine {
    private String name;

    public Engine(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

class Seat{
    private String name;

    public Seat(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

class Tyre{
    private String name;

    public Tyre(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

 

汽車構建:

public interface CarBuilder {
    Engine builderEngine();
    Seat builderSeat();
    Tyre builderTyre();
}

 

汽車裝配: 

public interface CarDirector {
    Car directorCar();
}

 

Hg牌汽車構建:

public class HgCarBuilder implements CarBuilder{

    @Override
    public Engine builderEngine() {
        System.out.println("構建Hg牌發動機");
        return new Engine("Hg牌發動機");
    }

    @Override
    public Seat builderSeat() {
        System.out.println("構建座椅");
        return new Seat("Hg牌座椅");
    }

    @Override
    public Tyre builderTyre() {
        System.out.println("構建輪胎");
        return new Tyre("Hg牌輪胎");
    }

}

 

Hg牌汽車裝配:

 

public class HgCarDirector implements CarDirector{
    private CarBuilder builder;
    
    public HgCarDirector(CarBuilder builder) {
        this.builder = builder;
    }

    @Override
    public Car directorCar() {
        Engine e = builder.builderEngine();
        Seat s = builder.builderSeat();
        Tyre t = builder.builderTyre();
        
        //裝配成汽車對象
        Car  car = new Car();
        car.setEngine(e) ;
        car.setSeat(s);
        car.setTyre(t);
        
        return car;
    }

}

實現:

 

public class Client {
    public static void main(String[] args) {
        CarDirector director = new HgCarDirector(new HgCarBuilder());
        
        Car car = director.directorCar();
        
        System.out.println(car.getEngine().getName());
        car.run();
    }
}

5.原型模式

經過new產生一個對象須要很是複雜的數據準備或訪問權限,則可以使用。

Cloneable接口和clone方法。

克隆羊接口:

public class Sheep implements Cloneable{ //克隆羊,多利
    private String name;
    private int age;
    
        @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();//返回Object對象的方法
    }

        public String getName() {
            return name;
        }

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

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        public Sheep(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }        
}

 

測試淺克隆:

public class Client {
    public static void main(String[] args) throws Exception {
        Sheep s1 = new Sheep("羊駝",18);
        Sheep s2 = (Sheep)s1.clone();
        
        System.out.println(s1.getName());
        System.out.println(s1.getAge());
        
        s1.setAge(17);
        
        System.out.println(s1.getAge());
        System.out.println(s2.getName());
        System.out.println(s2.getAge());
    }
}

 


 

2、結構型模式(實現鬆藕合)

1.適配器模式

  • 目標接口(Target):具體或抽象的類,能夠是接口
  • 適配的類(Adaptee):須要適配的類或適配者類
  • 適配器(Adapter):包裝一個須要適配的對象,把原接口轉換爲目標接口

 應用於舊系統改造和升級

 被適配的類:

public class Adaptee {
    public void request() {
        System.out.println("完成請求須要的功能");
    }
}

 

 適配器:

public class Adapter extends Adaptee implements Target{

    @Override
    public void handleReq() {
        super.request();
    }
}

 

目標接口:

public interface Target {
    void handleReq();
}

 

客戶端類、測試:

public class Client {
    public void test(Target t) {
        t.handleReq();
    }
    public static void main(String[] args) {
        Client c = new Client();
    
        Target t = new Adapter();
        
        c.test(t);
    }
}

2.橋接模式(bridge)

 處理多層繼承結構、多維度變化場景,將各個維度設計成獨立的繼承機構,使各個維度能夠獨立的擴展在抽象層創建關聯

應用於:JDBC、銀行日誌、獎金計算、OA系統消息處理

 銷售電腦例子

品牌維度:

public interface Brand {
    void sale() ;
}
class Lenovo implements Brand{

    @Override
    public void sale() {
        System.out.println("銷售聯想品牌");
    }
}
class Dell implements Brand{

    @Override
    public void sale() {
        System.out.println("銷售戴爾品牌");
    }
}

 

電腦類型維度:

public class Computer {
    protected Brand brand;

    public Computer(Brand b) {
        this.brand = b;
    }
    public void sale() {
        brand.sale();
    }
}

class Desktop extends Computer{

    public Desktop(Brand b) {
        super(b);
    }
    
    public void sale() {
    super.sale();
    System.out.println("銷售臺式機");
    }
}

class Laptop extends Computer{

    public Laptop(Brand b) {
        super(b);
    }
    
    public void sale() {
    super.sale();
    System.out.println("銷售筆記本");
    }
}

 

測試:

public class Client {
    public static void main(String[] args) {
        //銷售聯想牌筆記本
        Computer  c = new Laptop(new Lenovo());
        
        c.sale();
    }
}

3.裝飾模式(decorator)

  • 抽象構件Component:真實對象和裝飾對象有相同的接口
  • 具體構件ConcreteComponent:真實對象
  • 裝飾Decorator:持有一個抽象構件的引用
  • 具體裝飾ConcreteDecorator:負責給構件對象增長新的東西

汽車實現:

public interface ICar {
    void move();
}

//具體構件(真實對象)
class Car implements ICar{
    @Override
    public void move() {
        System.out.println("普通汽車");
    }
}

//裝飾角色
class SuperCar implements ICar{
    protected ICar car;

    public SuperCar(ICar car) {
        super();
        this.car = car;
    }

    @Override
    public void move() {
    car.move();
    }
}

//具體裝飾角色
class FlyCar extends SuperCar{

    public FlyCar(ICar car) {
        super(car);
    }
    
    private void fly() {
        System.out.println("能夠天上飛");
    }
    
    @Override
    public void move() {
        super.move();
        fly();
    }
}
//具體裝飾
class AICar extends SuperCar{

    public AICar(ICar car) {
        super(car);
    }
    
    private void Auto() {
        System.out.println("能夠自動駕駛");
    }
    
    @Override
    public void move() {
        super.move();
        Auto();
    }
}

 

測試:

 

public class Client {
     public static void main(String[] args) {
        Car car = new Car();
        car.move();
        
        System.out.println("添加飛行功能");
        FlyCar flycar = new FlyCar(car);
        flycar.move();
        
        System.out.println("添加自動駕駛功能");
        AICar  aicar = new AICar(car);
        aicar.move();
    }
}

 

 

 

 

4.組合模式(composite)

用於處理樹形結構,便於統一處理

應用於:操做系統資源管理器、GUI的容器層次圖、XML文件解析、OA中組織結構處理、Junit單元測試框架

核心:

  • 抽象構件(Component):定義葉子和容器構件的共同點
  • 葉子(Leaf)構件:無子節點
  • 容器(Composite)構件:有容器特徵,包含子節點

 

public interface Component {
    void operation();
}

//葉子組件
interface Leaf extends Component{
}

//容器組件
interface Composite extends Component{
    void add(Component c);
    void remove(Component c);
    Component getChild(int index);
}

 

 

 

5.外觀模式

爲子系統提供統一的入口。封裝子系統的複雜性,便於客戶端調用

6.享元模式FlyWeight

存在不少個徹底相同或類似的對象。能夠經過享元模式節省內存

 

 --享元模式一共享的方式高效地支持大量細粒度對象的重用。

 

        --享元模式對象能 作到共享的關鍵是區份內部狀態和外部狀態。

 

            -內部狀態:能夠共享,不會隨環境變化而變化。

 

            -外部狀態:不能夠共享,會隨着環境變化而改變。

 

模式實現:

  • 享元工廠類FlyweightFactory:建立並管理享元對象,享元池通常設計成鍵值對
  • 抽象享元類FlyWeight:接口或抽象類,聲明公共方法,這些方法能夠向外界提供對象的內部狀態,設置外部狀態
  • 具體享元類ConcreteFlyWeight:爲內部狀態提供成員變量進行存儲
  • 非共享享元類UnsharedConcreteFlyWeight:不能被共享的子類能夠設計爲非共享享元類

 

 

7.代理模式(proxy pattern)

  • 安全代理:屏蔽對真實角色的直接訪問
  • 遠程代理:經過代理類處理遠程方法調用
  • 延遲加載:先加載輕量級的代理對象,真正須要再加載真實對象。

靜態代理(靜態定義代理類):

抽象角色:

public interface Star {
    //聊天
    void talk();
    //籤合同
    void signContract();
    //唱歌
    void sing();
}

 代理:

public class ProxyStar implements Star{
    private Star star;
    
    public ProxyStar(Star star) {
        super();
        this.star = star;
    }

    @Override
    public void talk() {
        System.out.println("聊天");
    }

    @Override
    public void signContract() {
        System.out.println("籤合同");
    }

    @Override
    public void sing() {
        star.sing();
    }
}

真實類:

public class RealStar implements Star{

    @Override
    public void talk() {
        System.out.println("聊天");
    }

    @Override
    public void signContract() {
        System.out.println("籤合同");
    }

    @Override
    public void sing() {
        System.out.println("陳奕迅唱歌");
    }
}

測試:

public class Client {
    public static void main(String[] args) {
        Star real = new RealStar();
        Star proxy = new ProxyStar(real);
        
        proxy.talk();
        proxy.signContract();
        proxy.sing();
    }
}

 動態代理:(動態生成代理類)

  • java.lang.reflect.Proxy -->動態生成代理類和對象
  • java.lang.reflect.InvocationHandler(處理器接口)--> 經過invoke方法實現對真是角色的代理訪問。經過Proxy生成代理類對象時都要指定對應的處理器對象 

 代理類:

public class StarHandler implements InvocationHandler{
    Star realStar;
    
    public StarHandler(Star realStar) {
        super();
        this.realStar = realStar;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) 
            throws Throwable {
        Object object = null;
        
        if(method.getName().equals("sing")) {
            object = method.invoke(realStar, args);
        }
        return object;
    }
}

 

測試:

public class Client {
    public static void main(String[] args) {
        StarHandler handler = new StarHandler(new RealStar());
        
        Star proxy = (Star)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), 
                new Class[] {Star.class}, handler);
        
        proxy.sing();
        
    }
} 
相關文章
相關標籤/搜索