简体   繁体   English

需要澄清 - 设计模式

[英]Clarification required - Design Patterns

In most of the design patterns concepts, it was mentioned that "Has A" is better than "Is A" means. 在大多数设计模式概念中,有人提到“Has A”比“Is A”更好。

In the first chapter - Head First Design Patterns - "Intro to Design Patterns", section "Integrating the Duck Behaviour" (page no 15), the Duck class is having references to FlyBehavior and QuackBehavior interface types. 在第一章 - 头部设计模式 - “ 设计模式简介”,“整合鸭子行为”(第15页)一节中,Duck类引用了FlyBehavior和QuackBehavior接口类型。 For example, we are going to add a new behavior in feature name it XYZBehavior (just assume client has not yet decided it) for one kind of Ducks, we need to change the Duck class to have the reference to new interface. 例如,我们将在功能名称中添加一个新行为XYZBehavior(只是假设客户端还没有决定它)对于一种Ducks,我们需要更改Duck类以获得对新接口的引用。 Resulting, we need to alter the class but which should not happen according to good design pattern. 结果,我们需要改变类,但根据良好的设计模式不应该发生。

Can you suggest me how can we deal with this requirement? 你能建议我怎样才能处理这个要求?

That problem can be solved by using Dependency Injection 这个问题可以通过使用依赖注入来解决

(In Java usually through either Spring or Guice ) (在Java中通常通过SpringGuice

Here's a Beginner's Guide to dependency Injection 这是依赖注入初学者指南

Basically, a Bird would have a behaviors property: 基本上,Bird会有一个行为属性:

private Collection<Behavior> behaviors;
public void setBehaviors(Collection<Behavior> behaviors){
    this.behaviors = behaviors;
}

Now in a Configuration file you would specify which Behaviors get injected into the Bird without having to change the Bird class. 现在,在配置文件中,您可以指定将哪些行为注入Bird,而无需更改Bird类。

You can handle this scenario by using Composition => Duck has a list of Behaviours . 您可以使用Composition => Duck来处理此场景,其中包含一个Behaviours列表。

Duck will maintain a list of Behaviour objects. Duck将维护一个Behavior对象列表。 Populate relevant behaviours during creation of Duck object. 在创建Duck对象期间填充相关行为。

Sample code: 示例代码:

import java.util.*;

interface Behaviour{

}
class FlyBehaviour implements Behaviour{

}
class QuackBehaviour implements Behaviour{

}
class XYZBehaviour implements Behaviour{

}

public class Duck{
    private List<Behaviour> duckBehaviours = new ArrayList<Behaviour>();

    public Duck(List<Behaviour> list){
        duckBehaviours = list;
    }
    public static void main(String[] args){
        // set the behaviours
        List<Behaviour> list = new ArrayList<Behaviour>();
        list.add(new FlyBehaviour());
        list.add(new QuackBehaviour());
        list.add(new XYZBehaviour());
        Duck duck = new Duck(list);
    }   
}

The Strategy pattern does not prevent from changing the class if you add a new behaviour (strategy). 如果添加行为(策略),策略模式不会阻止更改类。 It just prevents from touching the class, if an existing behaviour (strategy) changes. 如果现有行为(策略)发生变化,它只会阻止触及类。

Example with QuackBehaviour: assume, we thought, a duck would sound like "quaack" but after some years of research we realised, that ducks actually sound like "quaaack". QuackBehaviour的例子:假设,我们认为,鸭子会听起来像“喧嚣”,但经过几年的研究,我们意识到,鸭子实际上听起来像“贪吃”。 We're lucky, we implemented a QuackBehaviour and just adjust the implemtation of the QuackBehaviour interface for common ducks. 我们很幸运,我们实施了一个QuackBehaviour,只是调整了常见鸭子的QuackBehaviour接口的实现。 That's the trick with this pattern. 这就是这种模式的诀窍。

If later on, we decide to add a SwimBehaviour, because another research team realized, that swimming is a common duck behaviour, then we have to touch the common duck and add that behaviour (to the Duck class). 如果稍后,我们决定添加一个SwimBehaviour,因为另一个研究小组意识到,游泳是一种常见的鸭子行为,那么我们必须触摸普通的鸭子并添加该行为(对于Duck类)。

Hope it helped! 希望它有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM