1. 程式人生 > >基本的幾個設計模式

基本的幾個設計模式

  • 簡單工廠模式
  • 單例模式
  • 建造者模式(Builder)
  • 原型模式(prototype)—克隆
  • 中介者模式(Mediator)
  • 代理模式
  • 觀察者模式(Observe)
  • 策略模式(strategy)
  • 狀態模式
  • 享元模式(Flyweight)
  • 裝飾器模式

簡單工廠模式

public interface Car(){
    public void run();
}
public class Audi implements Car(){
    @Override
    public void run(){
        System.out.println("奧迪在跑!");
    }
}
public
class Benz implements Car{ @Override public void run(){ System.out.println("賓士在跑!"); } } public class CarFactory{ public static Car createCar(String type){ Car c=null; if("奧迪".equals(type)){ c=new Audi(); }else if("賓士".equals(type)){ c=new
Benz(); } return c; } } public class Client{ public static void main(String []){ Car c1 =CarFactory.createCar("奧迪"); Car ce =CarFactory.createCar("賓士"); c1.run(); c2.run(); } }

這裡寫圖片描述
思考問題:
1.公司裡,辦公用品的領取過程?
2.sun公司設計java時,為解決作業系統之間的差異采用什麼手段?
3.Spring的ioc容器的作用,跟我們工廠模式的關係?
(BeanFactory,bean class=”” ..可以通過反射來new 物件。可以把每個new 物件放在map裡提高效率。)Factory一般用單例來做。
本質:將實現類、建立類物件統一管理控制,從而將客戶端程式跟我們的實現類解耦。

單例模式

保證一個類只有一個實現物件。(如serlvet)
思考如下場景:
1.專案中,讀取配置檔案的類,一般也只有一個物件。有無必要每次使用配置檔案資料,每次new一個物件去讀取?
懶漢式單例模式程式碼:

public class singletonDemo{
    private static SingletonDemo s;
    private SingletonDemo(){}; //私有化構造器
    public static synchronized SingletonDemo getInstance(){
    if(s==null){
        s=new SingletonDemo();
        }
        return s;
    }
}
public class Client(
    public static void main(String[] args){
        SingletonDemo s=singletonDemo.getInstance();
        SingletonDemo s2=singletongDemo.getInstance();
        System.out.println(s==s2);//結果為true
 餓漢式單例模式程式碼:
 public class SingletonDemo2{
        private statice SingletonDemo2 s=new SingletonDemo2();//第一次載入就被建立,不會發生執行緒衝突
        private SingletonDemo2(){} //私有化構造器
        public static singletonDemo2 getInstance(){
        return s;
        }
       }
    public class Client{
    public  statice void main(String [] args){
        SingletonDemo s=SingletonDemo.getInstance();
        SingletonDemo s1=SingletonDemo.getInstance();
        System.out.prinln(s==s2);//結果為true
        }
    }
    比如sessionfactory servlet都是單例

建造者模式(Builder)

場景:
1.我們要建造一個複雜的產品,比如:神舟飛船。這個複雜的產品的建立。有這樣一個問題需要處理:
裝配這些子組建是不是有個步驟問題。
2.實際開發中,我們所需要的物件構建時,也非常複雜,有很多步驟需要處理。

    public class Airship{
        private String orbitalModule;//軌道艙
        private String engine;//發動機
        private String escapeTower;//逃逸塔
        public String getOrbitalModule(){
            return orbitalModule;
        }
        public void setOrbitalModule(String orbitalModule){
            this.orbitalModule=orbitalModule;
            }
        public String getEngine(){
            return engine;
            }
        public void setEngine(String engine){
            this.engine=engine;
            }
        public String getEscaperTower(){
            return escapeTower;
            }
        public void setEscapeTower(StringescapeTower){
            this.escapeTower=escapeTower;
        }
    }
    public interface AirshipBuilder{
        public void builderEngine();
        public void builderOrbitalModule();
        public void buildderEscapeTower();
    }
    public class ConcreteAirshipBuilder implements AirshipBuilder{
        private Airship airship=new Airship();
        @Override
        public void buildderEscapeTower(){
            System.out.println("建築逃逸塔,over");
            airship.setEscapeTower("莫莫牌逃逸塔!");
        }
        @Override
        public void builderEngine(){
            System.out.println("建造發動機,over");
            airship.setEngine("莫莫牌火箭發動機");
            }
        @Override
        public void builderOrbitalModule(){
            System.out.println("建造軌道艙,over!");
            airship.setOrbitalModule("莫莫牌軌道艙");
        }
        public Airship getAirship(){
            return ariship;
        }
        public void setAirship(Airship airship){
            this.airship=airship;
        }
    }
    public class Director{//裝配順序指導
        public void creteAirship(AirshipBuilder builder){
            builder.builderEngine();
            builder.builderOrbitalModule();
            builder.builderEscaperTower();
        }
    }   
    public class Client{
        public statice void main(String [] args){
            ConcreteAirshipBuilder builder=new ConcreteAirshipBuilder();
            Diretor director =new Director();
            director.createAirship(builder);
            Airship shenzhou1=builder.getAirship();
            System.out.println(shenzhou1.getEngine());
            }
        }

建造者模式反應了構建類的細節,相當於流水線、裝配車間。(StringBuidler、xml解析)

原型模式(prototype)—克隆

場景:
1.思考一下:克隆技術是怎麼樣的過程?
2.javascript語言中,繼承怎麼實現?那裡面也有prototype.
就是java種的克隆技術,以某個物件為原型,複製出新的物件。他的優勢有:效率高(直接克隆,並且避免了重新執行構造過程的步驟)、”介面造介面”。
克隆類似於new ,但是不同於new .new 建立新的物件屬性採用的是預設值。克隆出的物件屬性值和原型物件相同。並且克隆出的新物件改變不會影響原型物件。

    public class Sheep implements Cloneable{
        private String name;
        @Override
        protected Object clone(){
            object obj=null;
            try{
                obj=super.clone();//直接呼叫父類的clone方法即可!
            }catch(CloneNotSupportedException e){
                e.printStackTrace();
            }
            return obj;
        }
        public String getSname{
            return sname;
        }
        public Sheep(){
            }
    }
    public class Client{
        public static void main(String [] args){
            Sheep s1=new Sheep("多利");
            Sheep s2=(Sheep)s1.clone();
            System.out.println(s1+"--"+s1.getSname());
            System.out.println(s2+"--"+s2.getSname());
        }

可能有深複製、淺複製;
淺克隆:
這裡寫圖片描述
深克隆:
這裡寫圖片描述
1.spring管理structs2總,action是否使用了prototype模式?

中介者模式(Mediator)

場景:
1.假如公司沒有總經理。下面三個部門:財務部、市場部、研發部。財務部要發工資,會非常複雜。
總經理和部門打交道

    public interface Department{
        void action();//做本部門的事情
        void advice();//像總經理髮出申請
    }
    public class Development implements Department{
        private President p;//總經理
        @Override
        public void action(){
            System.out.println("技術部在開發專案!");
        }
        @Override
        public void advice(){
            System.out.println("向總經理報告開發進度,需求資金支援!");
        }
        public Development(President p){
            super();
            this.p=p;
            p.reqesiter(this,2);
        }
        public Development()
        {}
    }
    public class Finacial implements Department{
        private President p;//總經理
        @Override
        public void action(){
            System.out.println("財務部在數錢!");
        }
        @Override
        public void advice(){
            System.out.println("發工資了!");
        }
        public Development(President p){
            super();
            this.p=p;
            p.reqesiter(this,3);
        }
        public Finacial()
        {}
    }
        public class Market implements Department{
        private President p;//總經理
        @Override
        public void action(){
            System.out.println("市場部在接專案!");
        }
        @Override
        public void advice(){
            System.out.println("市場部報告專案承接進度,需要資金支援!");
            p.receive(3);
        }
        public Development(President p){
            super();
            this.p=p;
            p.reqesiter(this,1);
        }
        public Market()
        {}
    }
    public interface Mediator{
       void regesiter(Department department,int type);
        void command(int type);
        void receive(int type);
    }
    public class President implements Mediator{
        Market m;
        Developmet d;
        Finacial f;
        @Override
        public void command(int type){
            switch(type){
                case 1:
                    m.action();
                    break;
                case 2:
                    d.action();
                    break;
                case 3:
                    f.action();
                    break;
                }       
            }
            @Override
    public void regesiter(Department department,int type){
                switch(type){
                    case 1:
                        m=(Market)department;
                        break;
                    case 2:
                        d=(Development) dapartment;
                        break;
                    case 3:
                        f=(Financial)department;
                        break;
                    }
                }
        @Override
        public void receive(int type){
            System.out.println("受到部門訊息!");
            command(type);
        }
    }
    public class Client{
        public static void main(String [] args){
            President p=new President();
            Market m=new Market(p);
            Development d=new Development(p);
            Finacial f=new Finacial(p);
            m.advice();
        }
    }
類圖:

這裡寫圖片描述
初級寫遊戲時,視窗類是中介者。

代理模式

1.資料庫連線池的動態代理的實現。
2.struct2 Invocation代理類返回一個aciotn
3.sprint AOP
動態代理是aop重要的手段。
思考下列問題:
1.結合動態代理模式,研究structs2中的控制流程Invocation 物件和代理原理。
2.hibernate中的懶載入時如何使用代理模式的?
3.aop的實現(攔截器都是aop的實現).(時序圖)

觀察者模式(Observe)

場景:
1.聊天室程式的建立。
2.主題的訂閱,當有新內容,則發給所有人。
3.大家一起玩cs遊戲,伺服器需要和、將每個人的方位變化發給所有的客戶。

    public interface Observer{
        void update(Subject subject);
    }
    public class ObserverA implements Observer{
        private int mystate;//需要讓觀察者的狀態和目標物件狀態保持一致!
        @Override
        public void update(Subject subject){
        mystate=((ConcreteSubject)subject).getState();
        }
        public int getMystate(){
            return mystate;
        }
        public void setMystate(int mystate){
            this.mystate=mystate;
        }
    }
    public class Subject{
private List<Observer> list=new ArrayList<Observer>();
        //註冊觀察者物件
        public void attach(Observer obs){
            list.add(obs);
        }
        //刪除觀察者
        public void delete(Observer obs){
            list.remove(obs);
        }
        //通知所有的觀察者更新目標物件的狀態
        protected void notifyAllObservers(){
            for(int i=0;i<list.size();i++){
                list.get(i).update(this);
            }
        }
    public class ConcreteSubject extends Subject{
        private int state;
        public  int getState(){
            return state;
        }
        public void setState(int state){
            this.state=state;
            this.notifyAllObervers();
        }
    }
    public class Client{
        public static void main(String [] args){
        ConcreteSubject subject=new ConcreteSubject();
        //建立觀察者
        ObserverA obs1=new ObserverA();
        ObserverA obs2=new ObserverA();
        //將上面兩個觀察者新增到subject的觀察隊伍中
        subject.attach(obs1);
        subject.attach(obs2);
        //改變subject的狀態
        subject.setState(1);
        //我們看看觀察者obs2的狀態是不是跟subject狀態同步
        System.out.println(obs2.getMystate());
    }

類圖:
這裡寫圖片描述
1.awt和swing中,事件處理是不是觀察者模式?
2.自學並說明,java.util.Observale的作為,並使用這個類來實現觀察者模式。

策略模式(strategy)

場景:
1.報價策略:
a)普通客戶小批量報價
b)普通客戶大批量報價
c)老客戶小批量報價
d)老客戶大批量報價
設計模式中有”開閉原則”,對擴充套件開放,對修改關閉。

    public interface Strategy{
        public double getprice(double standardprice);
    }
    public class NewCustomerfewStrategy implements Strategy{
        @override
        public double getPrice(double standardPrice){
            return standardPrice;
        }
    }
    public class NewCustomerManyStrategy implements Strategy{
        @Override
        public double getPrice(double standardPrice){
            return standardPrice*0.9;
        }
    }
    public class OldCustomerfewStrategy implements Strategy{
        @Override
        public double getPrice(double standardPrice){
            return standardPrice*0.85;
        }
    }
    public class OldCustomerfewStrategy implements Strategy{
        @Override
        public double getPrice(double standardPrice){
            return standardPrice*0.8;
        }
    }
    //負責與策略類互動 
    public class Context{
        private Strategy strategy;
        public Context(Strategy strategy){
            super();
            this.strategy=strategy;
        }
        public void printPrice(double s) { //打印出報價
  System.out.println("您的報價:"+strategy.getPrice(s));
        }
    }
    public class Client{
        public static void main(String[] args){
            Strategy s1=new OldCustomerfewStrategy();
            Context cxt=new Context(s1);
            cxt.printPrice(220);
        }
    }
某一個流程可以多種演算法實現,可以用策略模式。

狀態模式

場景:
1.某個物件狀態不同,對應處理方式不一樣。
2.公文流轉過程。狀態有提交、稽核、稽核未通過、稽核未通過、歸檔等狀態,對應處理也不同。
網購過程中,下訂單,付款。

    public interface State{
        void handle(String param);
    }
    public class BillState implements State{
        @Override
        public void handle(String param){
            System.out.println("下訂單:"+param);
        }
    }
    public class PayState implements State{
        @Override
        public void handle(String param){
            System.out.println("付賬:"+param);
        }
    }
    public class Context{
        private State state;
        public  void changeState(State s){
            state=s;
            state.handle("202");
    }
    public class Client{
        public static void main(String [] args){
            Context ctx=new Context();
            ctx.changeState(new BillState());
            ctx.changeStete(new PayState());
        }
    }
主要在業務邏輯層
工作流用到了設計模式。

享元模式(Flyweight)

場景:
1.一般用於快取的設計。
對於一些物件的屬性值變動不平凡,可以放記憶體中,設計享元

    public interface Font{
        public abstract void SetFont(String color,int size);
        public abstract void GetFont();
    }
    public class ConcreteFont implements Font{
        private String color;
        private int size;
        private String str;
        public ConcreteFont(String s){
            str=s;
        }
        public void SetFont(String _color,int _size){
            color=_color;
            size=_size;
        }
        public void GetFont(){
            System.out.println("String :"+ str+"---color---size is:"+size);
        }
    }
    public class FontFactory{
        private Hashtable charHashTable=new Hashtable();
        public Font GetFlyweight(String s){
            if(charHashTable.get(s)!=null){
                return (Font)charHashTable.get(s);
            }else{
                Font tmp=new ConcreteFont(s);
                charHashTable.put(s,tmp);
                return tmp;
            }
        }
        public Hashtable GetFactory(){
            return charHashTable;
        }
    }
    public class Test{
        public static void main(String [] args){
            FontFactory myFontFactory=new FontFactory();//一般將享元工廠設成單例
            Font f1=myFontFactory.GetFlyWeight("aa");
            Font f2=myFontFactory.GetFlyWeight("bb");
            Font f3=myFontFactory.GetFlyWeight("aa");
            System.out.println(f1);
            System.out.println(f2);
            System.out.println(f3);
        }
    }   
1.hibernate緩衝也是

裝飾器模式

場景:
    1.年底了,要發獎金.年終獎如何計算?
    a)當月基本獎金
    b)當月團隊獎金
    c)當年個人獎金
    d)當年團隊獎金

    最終拿到手的應該是上面這些計算的總和。
    public abstract class Component{
        abstract void operation();
    }
    public class ConcreteComponent extends Component{
        @override
        void operation(){
        System.out.println("我是被裝飾物件的operation方法!");
        }
    }
    public abstract class Decorator extends Component{
        protected Component component;
        public Decorator(Component component){
            this.component=component;
        }
    }
    @Override
    void operation(){
        System.out.println("我在呼叫被裝飾物件的operation方法之前!");
        component.operation();
        System.out.println("我在呼叫被裝飾物件的operation方法之後!");
        }
    }
    public class ConcreteDecoratorA extends Decorator{
    public ConcreteDecoratorA(Component component){
        super(component);
    }
    public void operation(){
        System.out.println("ConcreteDecoratorA中,可以在呼叫被裝飾方法前做某些處理!");
        super.operation();
        System.out.println("ConcreteDecoratorA中,可以在呼叫被裝飾方法後做某些處理!");
        }
    }
    public class Client{
        public static void main(String [] args){
            Component c=new ConcreteComponent();
            Decorator d=new ConcreteDecoratorA(c);
            d.operation();
        }
    }
inputstream 如:
InputStream is=new Fileinputstream("d:/a.txt");
InputStream bis=new BufferedReadReader(is);
bis.read();
structs2中request等物件的封裝處理;
request(map) 在servlet中為物件,利用裝飾器進行了封裝。