设计模式 Design Patterns

设计模式 Design Patterns

设计模式的基础:抽象,封装,多态,继承
良好的OO设计必须具备:可复用、可扩充、可维护三个特性
OO原则
  1. 合成/聚合复用原则:封装变化,多用组合,减少继承
  2. 针对接口编程,不针对实现编程
  3. 为交互对象之间的松耦合设计而努力
  4. 开放封闭原则:对扩展开放,对修改关闭
  5. 依赖倒置原则:依赖抽象不要依赖具体类
  6. 最少知识原则:一个对象应该对其他对象保持最少的了解
  7. 好莱坞原则:Don‘ t call us, we’ ll call you
  8. 单一责任原则:一个类应该只有一个引起变化的原因
类之间的关系:IS-A, HAS-A, IMPLEMENTS

 
 

策略模式 Strategy Pattern

定义

​ 定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
 

代码示例

public abstract class Duck{
   
    FlyBehavior flyBehavior;
    QuackBehavior quackBehavior;
    public Duck(){
   }
    pulbic void setFlyBehavior(FlyBehavior fb){
   flyBehavior = fb;}
    pulbic void setQuackBehavior(QuackBehavior qb){
   quackBehavior = qb;}
    public abstract void display();
    public void performFly(){
   
        flyBehavior.fly();
    }
    public void performQuack(){
   
        quackBehavior.quack();
    }
}

​ 鸭子所做的一组行为,即一族算法,可以利用set方法被替换,这种方法就是组合,将两个类结合起来使用,使用组合建立系统具有很大的弹性,可以在运行时动态地改变行为。

主要解决问题

​ 解决算法行为类似时,过多if…else…问题。

解决途径

​ 共同实现一个接口,将算法封装成类,需要时进行替换。
 
 

观察者模式 Observer Pattern

定义

​ 在对象之间定义了一对多的依赖,这样依赖,当一个对象改变状态,依赖他的对象都会收到通知并自动更新。

代码示例

public class WeatherData extends Observable{
   
    private float temperature;
    private float pressure;
    public void measurementsChanged(){
   
        setChanged();
        notifyObservers();
    }
    public void setMeasurements(float temperature,float pressure){
   
        this.temperature = temperature;
        this.pressure = pressure;
        measurementsChanged();
    }
    public float getTemperature(){
   ...};
    public float getPressure(){
   ...}}

public class ConditionDisplay implements Observer{
   
    Observable observable;
    private float temperature;
    private float pressure;
    public ConditionDisplay(Observable ob){
   
        this.observable = ob;
        observable.addObserver(this);
    }
    public void update(Observable obs, Object arg){
   
        if(obs instanceof WeatherData){
   
            WeatherData wd = (WeatherData) obs;
            this.temperature = wd.getTemperature();
            this.pressure = wd.getPressure();
            display();
        }
    }
    public void display(){
   
        print(...);
    }
}

​ 利用JDK内置支持,首先”主题“继承Observable接口,“观察者”实现Observer接口。在Observable类中,先调用setChange()方法,标记状态改变,在调用notifyObservers()方法,方法中会调用它的观察者的update()方法,其中参数Object arg可决定”推“或”拉“数据。

主要解决问题

​ 一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

解决途径

​ 实现Observable和Observer接口,通过遍历注册的观察者对象数组,广播通知。
 
 

装饰者模式 Decorator Pattern

定义

​ 动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

代码示例

public abstrack class Beverage{
   
    String description = "Unknown Beverage";
    public String get Description(){
   
        return description;
    }
    public abstract double cost();
}

pulbic abstract class CondimentDecorator extends Beverage{
   
    public abstract String get Description();
}
public class Espresso extends Beverage{
   
    public Espresso(){
   
        description = "Espresso";
    }
    public double cost(){
   
        return 1.99;
    }
}

public class HouseBlend extends Beverage{
   
    public HouseBlend(){
   
        description = "HouseBlend";
    }
    public double cost(){
   
        return 0.89;
    }
}
public class Mocha extends CondimentDecorator{
   
    Beverage beverage;
    public Mocha(Beverage beverage){
   
        this.beverage = beverage;
    }
    pulbic String getDescription(){
   
        return beverage.getDescription() + ", Mocha";
    }
    public double cost(){
   
        return 0.2 + beverage.cost();
    }
}
puvlic class CoffeeHouse{
   
    public static void main(String args[]){
   
        Beverage beverage = new Espresso();
        Beverage decoratedBeverage = new Mocha(beverage);
        print(decoratedBeverage.getDescription() + "$" +decoratedBeverage.cost());
    }
}

​ 保持类方法签名完整性的前提下,利用继承提供了额外的功能。我们需要有抽象组件(Beverage),具体组件(Espresso,HouseBlend),抽象装饰者(CondimentDecorator)以及具体修饰者(Mocha)。继承或实现接口的目的不是为了获得行为而是获得相同的类型。

主要解决问题

​ 防止单纯继承导致的子类膨胀问题。

解决途径

​ 通过继承和组合扩展父类。实现了对扩展开放对修改关闭。
 
 

工厂模式 Factory Pattern

定义

工厂模式是Java中最常用的设计模式之一

​ 简单工厂:不是工厂模式,只是OO编程习惯。

​ 工厂方法模式: 定义了一个创建对象的接口,但由于子类决定要求实例化的类时哪一个。工厂方法让类把实例化推迟到子类。

​ 抽象工厂模式: 提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

代码示例

简单工厂
public class SimplePizzaFactory{
   
    public Pizza createPizza(String type){
   
        Pizza pizza = nul;
        if(type.equals("cheese")){
   
            pizza = new CheesePizza();
        }else if(type.equals("pepperoni")){
   
            pizza = new PepperoniPizza();
        }
        return pizza;
    }
}

public class PizzaStore{
   
    SimplePizzaFactory factory;
    public PizzaStore(SimplePizzaFactory factory){
   
        this.factory = factory;
    }
    public Pizza orderPizza(String type){
   
        Pizza pizza;
        pizza = factory.createPizza(type);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }
}

​ 简单工厂利用组合,通过接收的参数不同返回不同的对象负责具体类的实例化,但是又缺点拓展性差,不符合开闭原则,不修改代码就无法拓展。

工厂方法模式
public abstract class PizzaStore{
   
    public Pizza orderPizza(String type){
   
        Pizza pizza;
        pizza = createPizza(type);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }
    protected abstract Pizza createPizza(String type);
}

public class NyPizzaStore extends PizzaStore{
   
    Pizza createPizza(String item){
   
        if(item.equals("cheese")){
   
            return new NYStyleCheesePizza();
        }else if(item.equals("pepperoni")){
   
            return new NYStylePepperoniPizza();
        }else return null;
    }
}

​ 工厂方法模式中,PizzaStore称为创建者类,其将实例化责任转移到一个方法中即createPizza(String),这样可以将处理对象的行为交给子类负责,超类代码和子类对象常见代码解耦,同时拓展性增强,支持增加新工厂产品。

抽象工厂模式
public interface PizzaIngredientFactory{
   
    public Dough createDough();
    public Cheese createCheese();
}

public class NYPizzaIngredientFactory implements PizzaIngredientFactory{
   
    public Dough createDough(){
   
        return new ThinCrustDough();
    }
    public Cheese createCheese(){
   
        return new ReggianoCheese();
    }
}

public abstract class Pizza{
   
    String name;
    Dough dough;
    Cheese cheese;
    abstract void prepare();
    void bake(){
   
        print("bake")
    }
    //cut..box
}

public class CheesPizza extends Pizza{
   
    PizzaIngredientFactory ingredientFactory;
    public CheesPizza(PizzaIngredientFactory ingredientFactory){
   
        this.ingredientFactory = ingredientFactory;
    }
    void prepare(){
   
        print("preparing");
        dough = ingredientFactory.createDough();
        cheese = ingredientFactory.createCheese();
    }
}

​ 引入抽象工厂,工厂方法使用类,而抽象工厂使用对象,通过对象的组合创建一个产品家族。抽象工厂定义了一个负责创建一族产品的接口,接口中每个方法都创建一个具体产品,并用子类实现具体的做法。因此抽象工厂也是利用工厂方法的思想实现的。

区分工厂方法和抽象工厂

工厂方法 抽象工厂
实现原理 利用继承 利用对象组合
扩展能力 支持增加新产品 支持增加产品族

主要解决问题

​ 封装对象的创建。

解决途径

​ 将类的实例化延迟到子类中进行。
 
 

单例模式 Singleton Pattern

定义

​ 确保一个类只有一个实例,并提供全局访问点。

代码示例

经典实现
public class Singleton{
   
    private static Singleton uniqueInstance;
    private Singleton(){
   }
    public static Singleton getInstance(){
   
        if(uniqueInstance == null){
   
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }
}

​ 用静态便令记录唯一一个实例,构造器声明为私有,禁止外部类调用构造

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值