1.工廠方法模式(Factory Method) 將程序中創建對象的操作,單獨出來處理,創建一個產品的工廠接口,把實際的工作轉移到具體的子類。大大提高了系統擴展的柔性,接口的抽象化處理給相互依賴的對象創建提供了最好的抽象模式。
- public class TestFactoryMethod {
- public static void main(String[] args) {
- AnimalFactory af=new DogFactory();
- Animal1 a=af.getAnimal();
- }
- }
- abstract class Animal1{}
- class Dog1 extends Animal1{}
- class Cat1 extends Animal1{}
- abstract class AnimalFactory{
- public abstract Animal1 getAnimal();
- }
- class DogFactory extends AnimalFactory{
- public Animal1 getAnimal(){
- System.out.println("Dog");
- return new Dog1();
- }
- }
- class CatFactory extends AnimalFactory{
- public Animal1 getAnimal(){
- System.out.println("Cat");
- return new Cat1();
- }
- }
2.抽象工廠模式(Abstract Factory) 針對多個產品等級的情況,而工廠方法模式針對單一產品等級的情況。
- import java.awt.*;
- import javax.swing.*;
- import java.awt.event.*;
- public class TestAbstractFactory {
- public static void main(String[] args) {
- GUIFactory fact=new SwingFactory();
- Frame f=fact.getFrame();
- Component c1=fact.getButton();
- Component c2=fact.getTextField();
- f.setSize(500,300);
- f.setLayout(new FlowLayout());
- f.add(c1);
- f.add(c2);
- f.setVisible(true);
- f.addWindowListener(new WindowAdapter(){
- public void windowClosing(WindowEvent e){
- System.exit(0);
- }
- });
- }
- }
- abstract class GUIFactory{
- public abstract Component getButton();
- public abstract Component getTextField();
- public abstract Frame getFrame();
- }
- class AWTFactory extends GUIFactory{
- public Component getButton() {
- return new Button("AWT Button");
- }
- public Frame getFrame() {
- return new Frame("AWT Frame");
- }
- public Component getTextField() {
- return new TextField(20);
- }
- }
- class SwingFactory extends GUIFactory{
- public Component getButton() {
- return new JButton("Swing Button");
- }
- public Frame getFrame() {
- return new JFrame("Swing Frame");
- }
- public Component getTextField() {
- return new JTextField(20);
- }
- }
- public class TestSingleton {
- public static void main(String[] args) {
- }
- }
- class ClassA{ //餓漢式
- private static ClassA i=new ClassA();
- public static ClassA newInstance(){
- return i;
- }
- private ClassA(){}
- }
- class ClassB{ //懶漢式
- private static ClassB i=null;
- public static synchronized ClassB newInstance(){
- if (i==null) i=new ClassB();
- return i;
- }
- private ClassB(){}
- }
4.建造模式(Builder) 將一個對象的內部表象和建造過程分割,一個建造過程可以造出不同表象的對象。可簡化爲模版方法模式.
- public class TestBuilder {
- public static void main(String[] args) {
- Builder b=new BuilderImpl1();
- Director d=new Director(b);
- Product p=d.createProduct();
- }
- }
- interface Builder{
- void buildPart1();
- void buildPart2();
- void buildPart3();
- Product getProduct();
- }
- class BuilderImpl1 implements Builder{
- public void buildPart1() {
- System.out.println("create part1");
- }
- public void buildPart2() {
- System.out.println("create part2");
- }
- public void buildPart3() {
- System.out.println("create part3");
- }
- public Product getProduct() {
- return new Product();
- }
- }
- class Director{
- Builder b;
- public Director(Builder b){
- this.b=b;
- }
- public Product createProduct(){
- b.buildPart1(); b.buildPart2();
- b.buildPart3();
- return b.getProduct();
- }
- }
- class Product{}
5.原型模式(ProtoType) 通過一個原型對象來創建一個新對象(克隆)。Java中要給出Clonable接口的實現,具體類要實現這個接口,並給出clone()方法的實現細節,這就是簡單原型模式的應用。 淺拷貝:只拷貝簡單屬性的值和對象屬性的地址 深拷貝:拷貝本對象引用的對象,有可能會出現循環引用的情況。可以用串行化解決深拷貝。寫到流裏再讀出來,這時會是一個對象的深拷貝結果。
- import java.io.*;
- public class TestClonealbe {
- public static void main(String[] args) throws Exception {
- Father f=new Father();
- User u1=new User("123456",f);
- User u2=(User)u1.clone();
- System.out.println(u1==u2);
- System.out.println(u1.f==u2.f);
- }
- }
- class User implements Cloneable,Serializable{
- String password;
- Father f;
- public User(String password,Father f){
- this.password=password;
- this.f=f;
- }
- public Object clone() throws CloneNotSupportedException {
- //return super.clone();
- ObjectOutputStream out=null;
- ObjectInputStream in=null;
- try {
- ByteArrayOutputStream bo=new ByteArrayOutputStream();
- out = new ObjectOutputStream(bo);
- out.writeObject(this);
- out.flush();
- byte[] bs=bo.toByteArray();
- ByteArrayInputStream bi=new ByteArrayInputStream(bs);
- in = new ObjectInputStream(bi);
- Object o=in.readObject();
- return o;
- } catch (IOException e) {
- e.printStackTrace();
- return null;
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- return null;
- }
- finally{
- try {
- out.close();
- in.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- class Father implements Serializable{}
結構模式 如何把簡單的類根據某種結構組裝爲大的系統
6.適配器模式(Adapter) 在原類型不做任何改變的情況下,用一個適配器類把一個接口轉成另一個接口,擴展了新的接口,靈活且多樣的適配一切舊俗。這種打破舊框框,適配新格局的思想,是面向對象的精髓。以繼承方式實現的類的 Adapter模式和以聚合方式實現的對象的Adapter模式,各有千秋,各取所長。
- public class TestAdapter {
- public static void main(String[] args) {
- USB mouse=new Mouse();
- PC pc=new PC();
- //pc.useMouse(mouse);
- PS2 adapter=new USB2PS2Adapter(mouse);
- pc.useMouse(adapter);
- }
- }
- interface PS2{
- void usePs2();
- }
- interface USB{
- void useUsb();
- }
- class Mouse implements USB{
- public void useUsb(){
- System.out.println("通過USB接口工作");
- }
- }
- class PC{
- public void useMouse(PS2 ps2Mouse){
- ps2Mouse.usePs2();
- }
- }
- class USB2PS2Adapter implements PS2{
- private USB usb;
- public USB2PS2Adapter(USB usb) {
- this.usb = usb;
- }
- public void usePs2(){
- System.out.println("把對usePS2的方法調用轉換成對useUSB的方法調用");
- usb.useUsb();
- }
- }
7.組合模式(Composite) 把整體和局部的關係用樹狀結構描述出來,使得客戶端把整體對象和局部對象同等看待。
- import java.util.*;
- public class TestComposite {
- public static void main(String[] args) {
- Node n1=new LeafNode(3);
- Node n2=new LeafNode(4);
- Node n3=new LeafNode(6);
- Node n4=new LeafNode(5);
- Node n5=new LeafNode(2);
- Node n6=new LeafNode(9);
- Node n7=new LeafNode(12);
- Node n8=new LeafNode(7);
- Node n9=new LeafNode(8);
- Node c1=new CompositeNode(n1,n2,n3);
- Node c4=new CompositeNode(n8,n9);
- Node c3=new CompositeNode(n5,c4);
- Node c2=new CompositeNode(n4,c3);
- Node c5=new CompositeNode(n6,n7);
- Node root=new CompositeNode(c1,c2,c5);
- System.out.println(root.getValue());
- }
- }
- abstract class Node{
- public abstract int getValue();
- }
- class LeafNode extends Node{
- int value;
- public LeafNode(int value){
- this.value=value;
- }
- public int getValue(){
- return value;
- }
- }
- class CompositeNode extends Node{
- private List children=new ArrayList();
- public CompositeNode(Node... nodes){
- for(Node n:nodes){
- children.add(n);
- }
- }
- public int getValue(){
- int result=0;
- for(Node n:children){
- result+=n.getValue();
- }
- return result;
- }
- }
8.裝飾模式(Decorator) 以對客戶透明的方式來擴展對象的功能。 用戶根據功能需求隨意選取組成對象的成分,通過方法的鏈式調用來實現。 可以給對象動態的增加功能,比繼承靈活性更大。
- public class TestDecorator {
- public static void main(String[] args) {
- Teacher t1=new SimpleTeacher();
- Teacher t2=new CppTeacher(t1);
- Teacher t3=new JavaTeacher(t2);
- t3.teach();
- //t.teach();
- }
- }
- abstract class Teacher{
- public abstract void teach();
- }
- class SimpleTeacher extends Teacher{
- public void teach(){
- System.out.println("Good Good Study, Day Day Up");
- }
- }
- class JavaTeacher extends Teacher{
- Teacher teacher;
- public JavaTeacher(Teacher t){
- this.teacher=t;
- }
- public void teach(){
- teacher.teach();
- System.out.println("Teach Java");
- }
- }
- class CppTeacher extends Teacher{
- Teacher teacher;
- public CppTeacher(Teacher t){
- this.teacher=t;
- }
- public void teach(){
- teacher.teach();
- System.out.println("Teach C++");
- }
- }
9.代理模式(Proxy) 用一個代理對象來作爲另一個對象的代理,對客戶來說是透明的。 存在一個抽象主題類,具體主題類和代理主題類都繼承(實現)抽象主題,代理主題類中的方法會調用具體主題類中相對應的方法。
10.享元模式(Flyweight Pattern) 對象的狀態分爲內蘊狀態和外蘊狀態。內蘊狀態不隨環境變化而變化,因此可以作成系統共享.
11.門面模式(Facade) 訪問子系統的時候,通過一個Façade對象訪問。Facade類是單例的。 客戶代碼只需要和門面對象通信,不需要和具體子系統內部的對象通信,使得他們之間的耦合關係減弱。 這次將表現層和邏輯層隔離,封裝底層的複雜處理,爲用戶提供簡單的接口,這樣的例子隨處可見。
門面模式很多時候更是一種系統架構的設計,在我所做的項目中,就實現了門面模式的接口,爲複雜系統的解耦提供了最好的解決方案。
12.橋樑模式(Bridge) 將抽象和實現脫耦,使得二者可以單獨變化。使得一個繼承關係不承擔兩個變化因素.使用合成來代替繼承的一種體現.
- public YuanUser(BankAccount account) {
- super(account);
- }
- public void getMoney() {
- System.out.print("人民幣");
- account.withdraw();
- }
- public void saveMoney() {
- System.out.print("人民幣");
- account.deposit();
- }
- }
- class DollarUser extends BankUser{
- public DollarUser(BankAccount account) {
- super(account);
- }
- public void getMoney() {
- System.out.print("美元");
- account.withdraw();
- }
- public void saveMoney() {
- System.out.print("美元");
- account.deposit();
- }
- }
行爲模式 描述如何在對象之間劃分責任
13.策略模式(Strategy) 如同LayoutManager和具體的佈局管理器的關係,在抽象策略類中定義方法,將易於變化的部分封裝爲接口,通常Strategy 封裝一些運算法則,使之能互換。Bruce Zhang在他的博客中提到策略模式其實是一種“面向接口”的編程方法,真是恰如其分。 在具體策略子類中實現,客戶代碼根據不同的需要選擇相應的具體類,例如電子商務中多種價格算法。 一種策略一旦選中,整個系統運行期是不變化的
- public class TestStrategy {
- public static void main(String[] args) {
- Strategy s1=new May1Strategy();
- Strategy s2=new June1Strategy();
- Book b=new Book(100);
- b.setS(s2);
- System.out.println(b.getPrice());
- }
- }
- class Book{
- Strategy s;
- public Book(double price){
- this.price=price;
- }
- private double price;
- public void setS(Strategy s) {
- this.s = s;
- }
- public double getPrice(){
- return price*s.getZheKou();
- }
- }
- interface Strategy{
- double getZheKou();
- }
- class May1Strategy implements Strategy{
- public double getZheKou(){
- return 0.8;
- }
- }
- class June1Strategy implements Strategy{
- public double getZheKou(){
- return 0.7;
- }
- }
- public class TestTemplateMethod {
- public static void main(String[] args) {
- XiaoPin xp=new DaPuKe();
- xp.act();
- }
- }
- abstract class XiaoPin{
- public abstract void jiaoLiu();
- public abstract void xuShi();
- public abstract void gaoXiao();
- public abstract void shanQing();
- public final void act(){
- jiaoLiu();
- xuShi();
- gaoXiao();
- shanQing();
- }
- }
- class DaPuKe extends XiaoPin{
- public void jiaoLiu(){
- System.out.println("順口溜");
- }
- public void xuShi(){
- System.out.println("火車除夕,老同學見面");
- }
- public void gaoXiao(){
- System.out.println("名片當作撲克");
- }
- public void shanQing(){
- System.out.println("馬家軍");
- }
- }
15.觀察者模式(Observer) 定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時, 所有依賴於它的對象都得到通知並被自動更新。觀察者和被觀察者的分開,爲模塊劃分提供了清晰的界限。在低耦合的對象間完成協調。 Java中的事件模型就是一個應用。
16.迭代器模式(Iterator) 類似於集合中的Iterator,使用迭代器來統一不同集合對象的遍歷方式。在絕大多數的系統中,都會用到數組、集合、鏈表、隊列這樣的類型,關心迭代模式的來龍去脈非常有必要。在遍歷算法中,迭代模式提供了遍歷的順序訪問容 器,GOF給出的定義爲:提供一種方法訪問一個容器(container)對象中各個元素,而又不需暴露該對象的內部細節。.NET中就是使用了迭代器來 創建用於foreach的集合。
- public class TestIterator {
- public static void main(String[] args) {
- Stack s=new Stack();
- s.push("Liucy");
- s.push("Huxz");
- s.push("George");
- LinkedList l=new LinkedList();
- l.addFirst("Liucy");
- l.addFirst("Huxz");
- l.addFirst("George");
- print(l.iterator());
- }
- public static void print(Itr it){
- while(it.hasNext()){
- System.out.println(it.next());
- }
- }
- }
- interface Itr{
- boolean hasNext();
- Object next();
- }
- class Stack{
- Object[] os=new Object[10];
- int index=0;
- private void expand(){
- Object[] os2=new Object[os.length*2];
- System.arraycopy(os,0,os2,0,os.length);
- os=os2;
- }
- public void push(Object o){
- if (index==os.length) expand();
- os[index]=o;
- index++;
- }
- public Object pop(){
- index--;
- Object o=os[index];
- os[index]=null;
- return o;
- }
- private class StackItr implements Itr{
- int cursor=0;
- public boolean hasNext(){
- return cursor}
- public Object next(){
- return os[cursor++];
- }
- }
- public Itr iterator(){
- return new StackItr();
- }
- }
- class LinkedList{
- private class Node{
- Object o;
- Node next;
- public Node(Object o){
- this.o=o;
- }
- public void setNext(Node next){
- this.next=next;
- }
- public Node getNext(){
- return this.next;
- }
- }
- Node head;
- public void addFirst(Object o){
- Node n=new Node(o);
- n.setNext(head);
- head=n;
- }
- public Object removeFirst(){
- Node n=head;
- head=head.getNext();
- return n.o;
- }
- class LinkedListItr implements Itr{
- Node currentNode=head;
- public boolean hasNext(){
- return this.currentNode!=null;
- }
- public Object next(){
- Node n=currentNode;
- currentNode=currentNode.getNext();
- return n.o;
- }
- }
- public Itr iterator(){
- return new LinkedListItr();
- }
- }
17.責任鏈(Chain of Responsibility) 多個處理器對象連成一串,請求在這條鏈上傳遞,由該處理這個請求的處理器來處理。發出請求的客戶端並不知道哪個對象處理請求。
- public class TestChain {
- public static void main(String[] args) {
- String pass1="123456";
- String pass2="123456";
- String personId="123456789012345678";
- String email="[email protected]";
- register(pass1,pass2,personId,email);
- }
- public static void register(String pass1,String pass2,String personId,String email){
- Filter f1=new PasswordFilter1();
- Filter f2=new PasswordFilter2();
- Filter f3=new PersonIdFilter();
- Filter f4=new EmailFilter();
- f1.setNext(f2);
- f2.setNext(f3);
- f3.setNext(f4);
- System.out.println(f1.doFilter(pass1,pass2,personId,email));
- }
- }
- abstract class Filter{
- Filter next=null;
- public Filter getNext() {
- return next;
- }
- public void setNext(Filter next) {
- this.next = next;
- }
- public String doFilter(String pass1,String pass2,String personId,String email){
- if (next==null) return "成功";
- else return next.doFilter(pass1,pass2,personId,email);
- }
- }
- class PasswordFilter1 extends Filter{
- public String doFilter(String pass1,String pass2,String personId,String email){
- if (!(pass1.equals(pass2)))
- return "兩次密碼輸入不一致";
- else return super.doFilter(pass1,pass2,personId,email);
- }
- }
- class PasswordFilter2 extends Filter{
- public String doFilter(String pass1,String pass2,String personId,String email){
- if (pass1.length()!=6)
- return "密碼長度必須爲6";
- else return super.doFilter(pass1,pass2,personId,email);
- }
- }
- class PersonIdFilter extends Filter{
- public String doFilter(String pass1,String pass2,String personId,String email){
- if (personId.length()!=15 && personId.length()!=18)
- return "身份證號碼非法";
- else return super.doFilter(pass1,pass2,personId,email);
- }
- }
- class EmailFilter extends Filter{
- public String doFilter(String pass1,String pass2,String personId,String email){
- int i1=email.indexOf("@");
- int i2=email.indexOf(".");
- if (i1==-1 || i2==-1 || i2-i1<=1 || i1==0 || i2==email.length()-1)
- return "email非法";
- else return super.doFilter(pass1,pass2,personId,email);
- }
- }
18.狀態模式(State) 在對象內部狀態改變時改變其行爲。把所研究的對象的行爲封裝在不同的狀態對象中。
- import static java.lang.System.*;
- public class TestState {
- public static void main(String[] args) {
- BBSUser u=new BBSUser();
- u.setState(new GuestState());
- u.publish();
- u.setState(new NormalState());
- u.publish();
- u.setState(new BlockedState());
- u.publish();
- u.setState(new NewComerState());
- u.publish();
- }
- }
- class BBSUser{
- private State state;
- public void setState(State state){
- this.state=state;
- }
- public void publish(){
- state.action();
- }
- }
- abstract class State{
- public abstract void action();
- }
- class GuestState extends State{
- public void action(){
- out.println("您處在遊客狀態,請先登錄");
- }
- }
- class NormalState extends State{
- public void action(){
- out.println("您處在正常狀態,文章發表成功");
- }
- }
- class BlockedState extends State{
- public void action(){
- out.println("您處在被封狀態,文章發表失敗");
- }
- }
- class NewComerState extends State{
- public void action(){
- out.println("您是新手,請先學習一下,3天后再來");
- }
- }
- class StateFactory{
- public static State createState(int i){
- if (i==1) return new GuestState();
- else return new NormalState();
- }
- }
19.備忘錄模式(Memento) 備忘錄對象用來存儲另一個對象的快照對象,保存其內部狀態,使得可以隨時恢復。 備忘錄角色:保存發起人對象的內部狀態,保護內容不被除發起人對象之外的對象獲取。窄接口:負責人對象和其他對象看到的接口,只允許把備忘錄對象傳給其他對象。寬接口:發起人能看到的接口,允許讀取內部狀態。 發起人角色:創建並使用備忘錄對象來保存其狀態 負責人角色:負責保存備忘錄對象。 白箱實現:備忘錄類對其他類也可見,這樣發起人的狀態可能會存在安全問題。 黑箱實現:把備忘錄類作成發起人的內部類,對外提供一個標識接口。
- public class TestMemento{
- public static void main(String[] args){
- Originator ori=new Originator();
- Caretaker c=new Caretaker();
- ori.setState("State 1");
- IFMemento m=ori.createMemento();
- c.save(m);
- ori.setState("State 2");
- m=c.retrieve();
- ori.restore(m);
- System.out.println("Now State:"+ori.getState());
- }
- }
- class Originator{
- String state;
- public void setState(String s){
- state=s;
- System.out.println("State change to: "+s);
- }
- public String getState(){
- return this.state;
- }
- public IFMemento createMemento(){
- return new Memento(state);
- }
- public void restore(IFMemento m){
- Memento mt=(Memento)m;
- this.state=mt.getState();
- }
- private class Memento implements IFMemento{
- private String state;
- public Memento(String s){
- this.state=s;
- }
- public String getState(){
- return this.state;
- }
- }
- }
- class Caretaker{
- private IFMemento m;
- public IFMemento retrieve(){
- return this.m;
- }
- public void save(IFMemento m){
- this.m=m;
- }
- }
- interface IFMemento{
- }