软件构造复习暨部分笔记(1)

本文深入探讨了设计模式的三大类别:创建型模式(如工厂方法)、结构型模式(如适配器、装饰器)和行为型模式(如策略、模板、迭代器和访问者模式)。这些模式提供了在软件设计中解决常见问题的标准化方法,提高了代码的可维护性和可扩展性。例如,工厂方法模式用于推迟实例化到子类,适配器模式用于接口转换,策略模式则允许在运行时动态选择算法。通过这些模式,开发者能够更好地组织代码并适应不断变化的需求。
摘要由CSDN通过智能技术生成

设计模式:adapter、decorator、strategy、template、 iterator/iterable、factory method、visitor:

创建型模式

      工厂方法模式(factory)

当 client 不知道要创建哪个具体类的实例,或者不想在 client 代码中 指明要具体创建的实例时,用工厂方法。定义一个用于创建对象的接口,让其子类来决定实例化哪一个类,从而使一个类的实例化延迟到其子类

例子如下:

interface TraceFactory {

public Trace getTrace();

public Trace getTrace(String type) ;

void otherOperation(){};

}

public class Factory2 implements TraceFactory {

public getTrace(string type) {

if(type.equals(file))

return new FileTrace();

else if (type.equals("system”))

return new SystemTrace();

}

结构型模式

适配器adapter:

将某个类/接口转换为 client 期望的其他形式,通过增加一个接口,将已存在的子类封装起来,cliet面向接口编程,从而隐藏了具体子类

interface Shape {

void display(int x1, int y1, int x2, int y2);

}

Adaptor类实现抽象接口

class Rectangle implements Shape {

void display(int x1,int y1, int x2,int y2) {

new LegacyRectangle().display(x1, y1, x2-x1, y2-y1);}

}

}

具体实现方法的适配

class LegacyRectangle {

void display( int x1, int y1, int w, int h) {...}

}

已存在的子类

class client {

Shape shape = new Rectangle();

public display() {

shape.display(xi, y1, x2,y2);

}

}

对抽象接口编程,与LegacyRectangle隔离

装饰器 decorator

用每个子类实现不同的特性 对每一个特性构造子类,通过委派机制增加到对象上

interface Stack {

void push( Item e);

Item pop( );

}

下面给出一个用于decorator的基础类

public abstract class StackDecorator implements Stack {

protected final stack stack;

public StackDecorator(Stack stack) {

this.stack = stack;                                                      Delegation

}

public void push(Item e) {

stack.push(e);

}

public Item pop() i

return stack.pop();

}

下面是具体的装饰子类

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);

}

行为类模式

策略 strategy

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

public interface PaymentStrategy {
public void pay(int amount);

}

public class PaypalStrategy implements PaymentStrategy {
private String emailId;
private String password;
public PaypalStrategy(String email, String pwd){
this.emailId=email;
this.password=pwd;
}
@Override
public void pay(int amount) {
System.out.println(amount + " paid using Paypal.");
}
}
public class ShoppingCart {
...
public void pay(PaymentStrategy paymentMethod){
int amount = calculateTotal();
paymentMethod.pay(amount);
}
}

客户端:

public class ShoppingCartTest {
public static void main(String[] args) {
    ShoppingCart cart = new ShoppingCart();
     Item item1 = new Item("1234",10);
     Item item2 = new Item("5678",40);
     cart.addItem(item1);
     cart.addItem(item2);
     //pay by paypal
     cart.pay(new PaypalStrategy("myemail@exp.com", "mypwd"));
     //pay by credit card
     cart.pay(new CreditCardStrategy(“Alice", "1234", "786", "12/18"));
}

}

模板(Template)

 做事情的步骤一样,但具体方法不同,共性的步骤在抽象类内公共实现,差异化的步骤在各个子类中实现,使用继承和重写实现模板模式

public abstract class OrderProcessTemplate {
public boolean isGift;
public abstract void doSelect();
public abstract void doPayment();
public final void giftWrap() {
System.out.println("Gift wrap done.");
}
public abstract void doDelivery();
public final void processOrder() {
doSelect();
doPayment();
if (isGift)
giftWrap();
doDelivery();
}
}

利用重写子类的方法实现

public class NetOrder
extends OrderProcessTemplate {
@Override
public void doSelect() { ... }
@Override
public void doPayment() { ... }
@Override
public void doDelivery() { ... }
}

迭代 (iterator)

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

让自己的集合类实现 Iterable 接口,并实现自己的独特 Iterator 迭代 器(hasNext, next, remove),允许客户端利用这个迭代器进行显式或隐式的迭代遍历

public class Pair<E> implements Iterable<E> {

private final E first, second;

public Pair(E f, E s) { first = f; second = s; }

public Iterator<E> iterator() {

return new PairIterator();

}

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();

}

}

} Pair<String> pair = new Pair<String>("foo", "bar");

for (String s : pair) { ... }

访问

对特定类型的 object 的特定操作(visit),在运行时将二者动态绑定到 一起,该操作可以灵活更改,无需更改被 visit 的类将数据和作用于数据上的某种/些特定操作分离开来为ADT预留一个将来可扩展功能的“接入点”,外部实现的功能代码 可以在不改变 ADT 本身的情况下通过 delegation 接入ADT

public interface ShoppingCartVisitor {
int visit(Book book);
int visit(Fruit fruit);
}
public class ShoppingCartVisitorImpl implements ShoppingCartVisitor {
public int visit(Book book) {
int cost=0;
if(book.getPrice() > 50){
cost = book.getPrice()-5;
}else
cost = book.getPrice();
System.out.println("Book ISBN::"+book.getIsbnNumber() + " cost ="+cost);
return cost;
}
public int visit(Fruit fruit) {
int cost = fruit.getPricePerKg()*fruit.getWeight();
System.out.println(fruit.getName() + " cost = "+cost);
return cost;
}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值