HeadFirst设计模式

时间:2022-07-22
本文章向大家介绍HeadFirst设计模式,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

设计原则一:把会变化的部分取出并“封装”起来,好让其他部分不受影响。

设计原则二:针对接口编程而不是针对实现编程。

针对实现编程就必须进行具体实现,针对接口编程,就可以对接口进行多态的调用

实现Animal接口,并创建所有的空方法。

实现Dog类,Cat类,实现具体的类

Animal animal = new Dog();
Animal animal = new Cat();

animal.bark()

这就会在运行时实现相应的方法

FlyBehavior 和 QuackBehavior 是飞和叫行为的接口

针对接口实现具体的飞行和叫的类

整合
public Duck(){
    QuackBehavior quackBehavior;
    public void performQuack(){
        quackBehavior.quack();
    }
}

抽象父类只负责实现相应功能不用管具体是哪一个实现。 子类想调用哪一个行为,就new一个新的行为。

public class MallardDuck extends Duck{
    
    public MallardDuck(){
        quackBehavior = new Quack();
        flyBehavior = new FlyWithWings();
    }
}
public interface FlyBehavior {
    void doFly();
}
public interface QuackBehavior {
    void doQuack();
}
public class FlyNoWings implements FlyBehavior {
    @Override
    public void doFly() {
        System.out.println("只能飞过墙头");
    }
}
public class FlyWithWings implements FlyBehavior {
    @Override
    public void doFly() {
        System.out.println("实现高度800米的飞翔");
    }
}
public class QuackMute implements QuackBehavior {
    @Override
    public void doQuack() {
        System.out.println("轻轻的叫");
    }
}
public class SQuack implements QuackBehavior {
    @Override
    public void doQuack() {
        System.out.println("呱呱的叫");
    }
}
abstract  public class Duck {

    FlyBehavior flyBehavior;
    QuackBehavior quackBehavior;


    public void performFly(){
        flyBehavior.doFly();
    }

    public void performQuack(){
        quackBehavior.doQuack();
    }

    public void setFlyBehavior(FlyBehavior flyBehavior){
        this.flyBehavior = flyBehavior;
    }

    public  void setQuackBehavior(QuackBehavior quackBehavior){
        this.quackBehavior = quackBehavior;
    }
}
public class SmallDuck extends Duck {

}
public class Main {

    public static void main(String[] args) {
        SmallDuck smallDuck = new SmallDuck();
        smallDuck.setFlyBehavior(new FlyNoWings());
        smallDuck.setQuackBehavior(new QuackMute());
        smallDuck.performFly();
        smallDuck.performQuack();
    }
}

观察者模式

出版者 + 订阅者 = 观察者模式

设计原则三:为了交互对象之间的松耦合而设计

/***
 *  主题需要提供注册,删除,全局通知接口
 */
public interface Subject {

    public void registerObserver(Observer o);
    public void removeRegister(Observer o);
    public void notifyObservers();
}

/***
 * 观察者接口需要提供观察者接受消息更新的统一接口
 */
public interface Observer {
    public void update(int temp,int humidity,int pressure);
}

/***
 * 展示模块,需要提供展示的统一接口
 */
public interface DisplayElement {
    public void display();
}

public class WeatherData implements Subject {

    private List<Observer> observerList = null;
    private int temp;
    private int humidity;
    private int pressure;

    public WeatherData(){
        observerList = new ArrayList<Observer>();
    }

    @Override
    public void registerObserver(Observer o) {
        observerList.add(o);
    }

    @Override
    public void removeRegister(Observer o) {
        int index = observerList.indexOf(o);
        observerList.remove(index);
    }

    @Override
    public void notifyObservers() {
        for (Observer it: observerList) {
            it.update(temp,humidity,pressure);
        }
    }

    public void measureChanged(){
        notifyObservers();
    }

    public void setMeasure(int temp,int humidity,int pressure){
        this.temp = temp;
        this.humidity = humidity;
        this.pressure = pressure;
        measureChanged();
    }
}

public class ForecastDisplay implements Observer, DisplayElement {

    private int temp;
    private int pressure;
    private Subject weatherData;

    public ForecastDisplay(Subject weatherData){
        this.weatherData = weatherData;
        weatherData.registerObserver(this);
    }
    @Override
    public void display() {
        System.out.println("temp is " + temp + " pressure" + pressure + " weatherData" + weatherData);
    }

    @Override
    public void update(int temp, int humidity, int pressure) {
         this.temp = temp;
         this.pressure = pressure;
         display();
    }
}

public class CurrentDisplay implements Observer, DisplayElement {

    private int temp;
    private int humidity;
    private Subject weatherData;

    public CurrentDisplay(Subject weatherData){
        this.weatherData = weatherData;
        weatherData.registerObserver(this);
    }

    @Override
    public void display() {
        System.out.println("Current conditions: " + temp + "F degrees and "+ humidity + "% humidity");
    }

    @Override
    public void update(int temp, int humidity, int pressure) {
        this.temp = temp;
        this.humidity = humidity;
        this.display();
    }

}

 public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();
        CurrentDisplay currentDisplay = new CurrentDisplay(weatherData);
        ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);

        weatherData.setMeasure(15,16,19);
    }

多用组合,少用继承。

观察者模式-在对象间定义一个一对多的依赖,这样。主题用一个 共同的接口更新观察者。 Swing ,JavaBeans,RMI,大量使用观察者模式。

装饰者模式

设计原则四,类应该对扩展开放,对修改关闭。

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

public abstract class Beverage {

    String description = "Unkown Beverage";

    public String getDescription(){
        return  description;
    }
    public abstract double cost();
}

public  abstract  class CondimentDecorator extends  Beverage {
    public abstract String getDescription();
}

public class DarkRoast extends CondimentDecorator {
    Beverage beverage;

    public DarkRoast(Beverage beverage){
        this.beverage = beverage;
    }
    @Override
    public String getDescription() {
        return beverage.getDescription() + ", DarkRoast";
    }

    @Override
    public double cost() {
        return beverage.cost() + 0.36;
    }
}

public class Espresso extends Beverage {

    public Espresso(){
        description = "Espresso";
    }
    @Override
    public double cost() {
        return 1.99;
    }
}
public class HouseBlend extends Beverage {

    public HouseBlend(){
        description = "HouseBlend";
    }

    @Override
    public double cost() {
        return 0.89;
    }
}

public class Mocha extends CondimentDecorator {
    Beverage beverage;

    public Mocha(Beverage beverage){
        this.beverage = beverage;
    }
    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Mocha";
    }

    @Override
    public double cost() {
        return beverage.cost() + .20;
    }
}

 public static void main(String[] args) {
        Beverage beverage = new Espresso();
        Beverage beverage1 = new HouseBlend();

        Beverage sum = new Mocha(beverage);
        System.out.println(sum.getDescription());
        Beverage sum1 = new DarkRoast(sum);
        System.out.println(sum1.getDescription() + sum1.cost());
}

java I/O中有大量装饰器的实现代码,InputStream,FileInputStream,StringBufferInputStream

装饰器是除了继承外的另一种扩展方式。

装饰器可以在被装饰者的行为面前加上自己的行为,甚至被装饰者整个行为被去掉。

工厂模式

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

设计原则五,要依赖抽象,不要依赖具体类。

/**
 * 创建接口
 */
public interface Shape {
     void draw();
}
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("draw a Circle ~~");
    }
}
public class Rectangle implements Shape {

    @Override
    public void draw() {
        System.out.println("draw a new Rectangle ~~~");
    }
}
public class ShapeFactory {

    public Shape getShape(String shapeType){
        if(shapeType==null){
            return null;
        }
        if(shapeType.equalsIgnoreCase("CIRCLE")){
            return  new Circle();
        }else if(shapeType.equalsIgnoreCase("RECTANGLE")){
            return  new Rectangle();
        }

        return null;
    }
}
public class Main {

    public static void main(String[] args) {
        ShapeFactory shapeFactory = new ShapeFactory();

        //获取circle
        Shape shape1 = shapeFactory.getShape("CIRCLE");
        Shape shape2 = shapeFactory.getShape("RECTANGLE");
        shape1.draw();
        shape2.draw();
    }
}

单例模式

有些对象我们只需要一个:线程池,缓存,对话框等等。

含有私有构造器的类不能被实例化

public class Singleton {
    private static Singleton uniqueInstance;
    private Singleton(){}
    public static Singleton getInstance(){
        if(uniqueInstance==null){
            return new Singleton();
        }else{
            return uniqueInstance;
        }
    }
}

命令模式

实现命令接口,让所有命令对象实现包含相同方法的接口。

命令模式,就是将实体类的方法的执行进行封装

  • 实现统一的方法执行接口,对每一个方法的执行实现一个类的封装
  • 实现 对Command的传入,执行
class Light{
    public void on {
        print("light is on")
    }
    public void off {
        print("light is off")
    }
}
public interface Command {
    public void execute();
}
public class LightOnCommand implements Command{
    Light light;
    public LightOnCommand(Light light){
        this.light = light
    }
    
    public void execute(){
        light.on()
    }
}

实现接口的传入,与执行这样和底层进行分开,实现的单独的命令执行

public class SimpleRemoteControl{
    Command solt;
    
    public SimpleRemoteControl(){}
    public void setCommand(Command command){
        slot = command;
    }
    public void buttonWasPassed(){
        slot.execute();
    }
}

适配器模型

适配器,相当于两个类的对接接口

A 强转 B 适配器的实现是创建一个类,实现B接口,同时通过构造函数传参A,在实现的B的方法中执行A方法。

B接口与实现类

public interface Duck{
    public void quick();
    public void fly();
}
public class MallarDuck implements Duck{

   public void quick(){
       print("Quick")
   }
   public void fly(){
       print("fly")
   }
}

A接口与实现类

public interface Turkey{
    public void gobble();
    public void fly();
}
public class WildTurkey implements Turkey{
    public void gobble(){
        print("GOOBLE")
    }
    public void fly(){
        print("Fly")
    }
}

适配器

public TurkeyAdapter implements Duck{
    Turkey turkey;
    
    public TurkeyAdapter(Turkey turkey){
        this.turkey = turkey;
    }
    public void quack(){
        turkey.gobble();
    }
    public void fly(){
        turkey.fly()
    }
}

模板模式

模板方法把一类的操作给单独抽出来

public abstract class CaffeineBeverageWithHook {

    //提出公共的方法流程
    void prepareRecipe(){
        boilWater();
        brew();
        pourInCup();
        if(customerWantsCondiments()){
            addCondiments();
        }
    }

    //不同饮料,最大的不同点,可以抽象化
    abstract  void  brew();

    abstract  void  addCondiments();

    void boilWater(){
        System.out.println("boiling water");
    }

    void pourInCup(){
        System.out.println("pouring into cup");
    }

    boolean customerWantsCondiments(){
        return true;
    }
}
public class CoffeeWithHook extends  CaffeineBeverageWithHook {
    @Override
    void brew() {
        System.out.println("Dripping Coffee through filter");
    }

    @Override
    void addCondiments() {
        System.out.println("Adding Suger and Milk");
    }

    public  boolean customerWantsCondiments(){
        String answer = getUserInput();

        if(answer.startsWith("y")){
            return true;
        }else{
            return  false;
        }
    }

    private String getUserInput(){
        String answer = null;
        System.out.println("Would you like milk and sugar with your coffee (y/n)");
        return  answer;
    }
}

迭代器模式

public interface Iterator{

    boolean hasNext();

    Object next();
}
public class MenuItem {

    String name;
    String description;
    boolean vegetarian;
    double  price;

    public MenuItem(String name,String description,boolean vegetarian,double price){
        this.name = name;
        this.description = description;
        this.vegetarian = vegetarian;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public boolean isVegetarian() {
        return vegetarian;
    }

    public void setVegetarian(boolean vegetarian) {
        this.vegetarian = vegetarian;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}
/**
 * 针对接口编程,对于每一个数组或者集合实现Iterator ,这样对于数组和列表的遍历
 * 在程序底层只用实现对Iterator的遍历
 */
public class DinerMenuIterator implements Iterator {
    MenuItem[] items;
    int position = 0;

    public  DinerMenuIterator(MenuItem[] items){
        this.items = items;
    }
    @Override
    public boolean hasNext() {
        if(position>=items.length || items[position] == null){
            return false;
        }else {
            return true;
        }
    }

    @Override
    public Object next() {
        MenuItem menuItem = items[position];
        position = position + 1;
        return menuItem;
    }
}
public class PanCakeMenuIterator implements Iterator {
    ArrayList<MenuItem> items;
    int position = 0;

    public PanCakeMenuIterator(ArrayList<MenuItem> items){
        this.items = items;
    }

    @Override
    public boolean hasNext() {
        if(position == items.size() || items.get(position) ==null){
            return false;
        }else {
            return true;
        }
    }

    @Override
    public Object next() {
        MenuItem item = items.get(position);
        position = position + 1;
        return item;
    }
}