欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

软件构造心得体会:设计模式期末总结

程序员文章站 2024-02-09 15:53:46
...

本学期的学习就这样结束了,在本学期的学习课程中,最重要的,也是对我们编程生涯最重要的,就是各种设计模式的运用,有的面向可复用的有的面向可维护的,下面对部分实现较为麻烦的进行简单总结。

目录

可维护

       State Pattern

       Memento Pattern

       Visitor

       Factory Method pattern

       Abstract Factory

可复用

      Strategy模式

      Decorator

      Iterator


可维护

State Pattern

对于某一个类,如果它具有某种属性,那么我们以前可能会通过各种ifelse语句来进行判断。但是这样非常不利于我们今后扩展新状态,所以我们利用形式语言与自动机的思想,做了这样一个基于状态的设计模式,将类中管理一个state,将其委派给其他类管理。

class Context {
State state; //保存对象的状态
//设置初始状态
public Context(State s) {state = s;}
//接收外部输入,开启状态转换
public void move(char c) { state = state.move(c); }
//判断是否达到合法的最终状态
public boolean accept() { return state.accept(); }
public State getState() { return this.state; } 
}

下面是我的状态接口及其实现,其中accept函数用来确定其是否达到最终状态

 //状态接口
    public interface State {
        State move(char c);
        boolean accept();
    }


    class State1 implements State {
        static State1 instance = new State1(); //singleton模式 (see 8-3) 
        private State1() {}
        public State move (char c) {
            switch (c) {
                case 'a': return State2.instance; //返回新状态的singleton实 例
                case 'b': return State1.instance;
                default: throw new IllegalArgumentException();
            } }
        public boolean accept() {
            return false;
        } //该状态非可接受状态
    } 

Memento Pattern

与状态模式相关联的,还有一个备忘录模式,对于之前的状态模式,我们可能会存在需要回滚到它的某个历史状态的情况,这就是我们的备忘录模式。
下面用Menento管理一个历史状态

 class Memento {
        private State state;
        public Memento(State state) {
            this.state = state;
        }
        public State getState() {
            return state;
        } 
    }

原来需要管理状态的ADT增加一个方法


    public void restore(Memento m) {
        state = m.getState();
        System.out.println("Originator: State after restoring from Memento: " + state);
    }

然后用一个类管理一个历史状态列表,并管理去除管状态的方法

   class Caretaker {
        private List<Memento> mementos
                = new ArrayList<>();
        public void addMemento(Memento m) {
            mementos.add(m);
        }
        public Memento getMemento() {
            return mementos.get(?);
        }
    }

Visitor

本方法为ADT预留一个将来可扩展功能的“接入点”,外部实现的功能代码可以在不改变ADT本身的情况下通过delegation接入ADT

下面举一个我实现例子,只简略实现必要接口

   public interface element{
        public void accept(avistor visitor);

    }
    public Aelement implements element{
        private final String x=  "x"
        public void accept(avistor visitor)
        {
            visitor.visit(this);
        }
        public String getx()
        {
            return x;
        }
    }

上面是我的ADT

public interface avisitor{
        public void accept(avistor visitor);

    }
    public avisitorimpl implements element{
        private final String =  "x"
        public void visit(Aelement  a)
        {
            System.out.println(a.getx);
        }
    }

上面是我的游客ADT,若是想要增加新的功能,只需要增加新的实现即可。
客户端

avisitor w=new avisitorimpl();
element   a=new Aelement();
a.accept(w);

Factory Method pattern

工厂方法模式,就是创建实例时用来隐藏具体类,把实例化这一过程放在方法中实现,我们常常使用静态方法实现下面例子:

public interface animalFactory {
     static  public animal   creatduck(){
        return  Duck;
        };
      static  public animal   creatcow(){
        return  cow;
        };
}

Abstract Factory

对于普通的工厂方法,我们同过静态方法隐式地返回一个实例,而抽象工厂方法,则是返回具有多个属性的一种搭配,帮助客户进行搭配。

可复用

Strategy模式

该模式有多种不同的算法来实现同一个任务,但需要client根据需要动态切换算法,而不是写死在代码里,为不同的实现算法构造抽象接口,利用delegation,运行时动态传入client倾向的算法类实例。

public interface actor()
{
    public  void  act();
}
public class act1 implements actor()
{
    public  String  act(){
           return "act1";
    }
}
public class act2 implements actor()
{
    public  String  act(){
           return "act2";
    }
}

上面是我实现act操作所实现的两个不同的类
然后构造ADT

public interface at()
{
    public  void  act();
}
public class AT1 implements at()
{
    public  void  act(actor x){
          x.act
    }
}

客户端通过调用不同的构造不同类型的实例对象来做这件事

AT OP=new  at;
actor m1=new act1();
actor m2=new act2();
OP.act(m1);
OP.act(m2);

Decorator

为对象增加不同侧面的特性,对每一个特性构造子类,通过委派机制增加到对象上
首先实现一个最顶层的接口

interface Stack {
     void push(Item e);
     Item pop();
}

然后实现最基本的功能

public class ArrayStack implements Stack {
     ... //rep
     public ArrayStack() {...}
     public void push(Item e) {
     ...
     }
     public Item pop() {
     ...
     }
 ...
}

然后创建一个抽象实例类

public abstract class StackDecorator implements Stack {
     protected final Stack stack;

     public StackDecorator(Stack stack) {
        this.stack = stack;
     }

     public void push(Item e) {
        stack.push(e);
     }

     public Item pop() {
        return stack.pop();
     }
     ...

在构造函数内将其委派给其他stack,注意他的每个子类都是stack类型,为最顶层的接口

若想要增加新的功能,则构造一个实例类继承抽象类,并将其特性加入方法中

public class UndoStack extends StackDecorator implements Stack {
      private final UndoLog log = new UndoLog();

      public UndoStack(Stack stack) { 
         super(stack); 
      }

      public void push(Item e) {
         log.append(UndoLog.PUSH, e);
         super.push(e);
      }

      public void undo() {
         //implement decorator behaviors on stack
      }
   ...
}

具体客户端操作时

 Stack t = new SecureStack(new SynchronizedStack(new UndoStack(s));

客户端需要一个具有多种特性的object,通过一层一层的就像一层一 装饰来实现,就像穿衣服

Iterator

客户端希望遍历被放入容器/集合类的一组ADT对象,无需关心容器的具体类型也就是说,不管对象被放进哪里,都应该提供同样的遍历方式
Iterable接口:实现该接口的集合对象是可迭代遍历的

public interface Iterable<T> {
    ...
    Iterator<T> iterator();
}

下面给出Iterator实现。

**private class PairIterator implements Iterator<E> {
private boolean seenFirst = false, seenSecond = false;
public boolean hasNext() { return !seenSecond; }
public E next() {
if (!seenFirst) { seenFirst = true; return first; }
if (!seenSecond) { seenSecond = true; return second; }
throw new NoSuchElementException();
}
public void remove() {
throw new UnsupportedOperationException();
} } }**