这是 java 中桥接模式的正确实现吗?
Is this a correct implementation of Bridge pattern in java?
我正在努力提高我对设计模式的了解,我对 Bridge 模式有点困惑。下面你可以看到我的例子:
public interface Animal {
public abstract void eat();
public abstract void move();
}
public class Jaguar implements Animal{
@Override
public void eat() {
System.out.println("The Jaguar eats meat");
}
@Override
public void move() {
System.out.println("The Jaguar runs");
}
}
public class Kangaroo implements Animal{
@Override
public void eat() {
System.out.println("THe Kangaroo eats grass and other vegetables");
}
@Override
public void move() {
System.out.println("The Kangaroo hops around :)");
}
}
public abstract class Environment {
private Animal animal;
public Environment(Animal animal){
this.animal = animal;
}
public void someAnimalEats(){
this.animal.eat();
}
public void someAnimalMoves(){
this.animal.move();
}
public abstract void environmentPolutionStatus();
}
public class Australia extends Environment{
public Australia(Animal animal) {
super(animal);
}
@Override
public void environmentPolutionStatus() {
System.out.println("Australia is in good shape as far as polution is concerned.");
}
}
public class Africa extends Environment{
public Africa(Animal animal) {
super(animal);
}
@Override
public void environmentPolutionStatus() {
System.out.println("Africa looks pretty good, however the hunting is kind of bad");
}
}
public class BridgePatternMain {
public static void main(String[] args){
Environment australiaKangaroo = new Australia(new Kangaroo());
Environment australiaJaguar = new Australia(new Jaguar());
Environment africaKangaroo = new Africa(new Kangaroo());
Environment africaJaguar = new Africa(new Jaguar());
australiaKangaroo.environmentPolutionStatus();
australiaKangaroo.someAnimalEats();
australiaKangaroo.someAnimalMoves();
australiaJaguar.environmentPolutionStatus();
australiaJaguar.someAnimalEats();
australiaJaguar.someAnimalMoves();
africaKangaroo.environmentPolutionStatus();
africaKangaroo.someAnimalEats();
africaKangaroo.someAnimalMoves();
africaJaguar.environmentPolutionStatus();
africaJaguar.someAnimalEats();
africaJaguar.someAnimalMoves();
}
}
我的问题:
- 这是正确的桥接模式吗?
- 如果将接口替换为
abstract classes(我在这个教程中看到了这种方法
http://www.newthinktank.com/2012/10/bridge-design-pattern-tutorial/)。
但是根据这个
(https://dzone.com/articles/design-patterns-bridge) 好像
就我而言,动物不应该是抽象的 class..
- 是否需要方法
someAnimalEats()
和
someAnimalMoves()
在环境 class 中?更准确地说,是不是
必须在此 class 中具有与每个对应的方法
来自 Animal 接口的方法?
非常感谢!
它具有 Bridge 模式的结构,因为它具有模式中典型的那种 class 关系和方法。我不确定您示例的语义是否适合这种模式。此模式的主要要点是您有一个使用一个或多个 实现 class 的 class。你会说你的 Animal
classes 提供 Environment
的实现吗?
是的,你确实可以使用抽象classes。请记住,设计模式是典型的语言不可知论者。在某些语言中,例如 C++,接口是使用包含纯抽象方法的 classes 创建的,因为与 Java 不同,C++ 中没有用于接口的特定关键字。图中的标签 "interface" 表示概念意义上的接口,而不是实际的 Java 关键字。事实上,您甚至可以使用具体的 class 作为您的实现者,尽管使用接口通常是一种很好的做法,因为它提供了更大的灵活性。
不,没有必要使用与实现者 classes 完全相同的方法。实现者 classes 提供了许多被其他 class 使用的实现方法。它如何使用它们取决于 class 想要提供的功能。
Bridge 模式在其他语言中更有用,例如 C++,它被称为 "pImpl idiom" 或 "opaque pointer",因为它可以用来对用户隐藏实现:他们不能查看有关实施的任何信息 class。在Java中,这种隐藏是不可能的。
- 您展示的领域(动物及其环境)并不是桥接模式的良好用例。它有一个非常具体的目的:将抽象(包括该抽象的扩展)与实现(同样可能包括扩展)分开。关键特征之一是抽象引用实现(名称中的 'bridge')而不是扩展或实现抽象的实现。一般具体实施由客户在运行-时间决定。
很难想到模拟真实世界对象(如动物和环境)的桥梁的自然用例。更容易想到旨在执行某些功能的 class。
// abstraction
abstract class Logger {
protected final LogOutputter outputter;
public abstract void log(String message);
}
// abstraction extension
class ErrorLogger extends Logger {
public void log(String message) {
outputter.output("Error: " + message);
}
}
// implementation interface
interface LogOutputter {
void output(String message);
}
// implementation extensions
class FileLogOutputter implements LogOutputter ...
class ConsoleLogOutputter implements LogOutputter ...
客户可能会做类似的事情:
Logger logger = new ErrorLogger(new FileLogOutputter("errors.log"));
我建议我在此示例中使用的 class / 接口组合非常典型。您可以进行抽象和接口,但考虑到桥接点是引用实现,因此更容易使其成为抽象 class.
希望这个例子也能回答这个问题:你可以在抽象和实现中有类似的方法,但这当然不是必需的。该模式有趣且有用的方面之一是不同的独立特征(在本示例中,记录的内容和记录方式)可以单独定义为抽象和实现的扩展。这使您可以混合和匹配特征,而不会出现 class 结构失控的情况。这些特性的独立性(即正交性)往往会要求两种结构中的方法完全不同。
我正在努力提高我对设计模式的了解,我对 Bridge 模式有点困惑。下面你可以看到我的例子:
public interface Animal {
public abstract void eat();
public abstract void move();
}
public class Jaguar implements Animal{
@Override
public void eat() {
System.out.println("The Jaguar eats meat");
}
@Override
public void move() {
System.out.println("The Jaguar runs");
}
}
public class Kangaroo implements Animal{
@Override
public void eat() {
System.out.println("THe Kangaroo eats grass and other vegetables");
}
@Override
public void move() {
System.out.println("The Kangaroo hops around :)");
}
}
public abstract class Environment {
private Animal animal;
public Environment(Animal animal){
this.animal = animal;
}
public void someAnimalEats(){
this.animal.eat();
}
public void someAnimalMoves(){
this.animal.move();
}
public abstract void environmentPolutionStatus();
}
public class Australia extends Environment{
public Australia(Animal animal) {
super(animal);
}
@Override
public void environmentPolutionStatus() {
System.out.println("Australia is in good shape as far as polution is concerned.");
}
}
public class Africa extends Environment{
public Africa(Animal animal) {
super(animal);
}
@Override
public void environmentPolutionStatus() {
System.out.println("Africa looks pretty good, however the hunting is kind of bad");
}
}
public class BridgePatternMain {
public static void main(String[] args){
Environment australiaKangaroo = new Australia(new Kangaroo());
Environment australiaJaguar = new Australia(new Jaguar());
Environment africaKangaroo = new Africa(new Kangaroo());
Environment africaJaguar = new Africa(new Jaguar());
australiaKangaroo.environmentPolutionStatus();
australiaKangaroo.someAnimalEats();
australiaKangaroo.someAnimalMoves();
australiaJaguar.environmentPolutionStatus();
australiaJaguar.someAnimalEats();
australiaJaguar.someAnimalMoves();
africaKangaroo.environmentPolutionStatus();
africaKangaroo.someAnimalEats();
africaKangaroo.someAnimalMoves();
africaJaguar.environmentPolutionStatus();
africaJaguar.someAnimalEats();
africaJaguar.someAnimalMoves();
}
}
我的问题:
- 这是正确的桥接模式吗?
- 如果将接口替换为 abstract classes(我在这个教程中看到了这种方法 http://www.newthinktank.com/2012/10/bridge-design-pattern-tutorial/)。 但是根据这个 (https://dzone.com/articles/design-patterns-bridge) 好像 就我而言,动物不应该是抽象的 class..
- 是否需要方法
someAnimalEats()
和someAnimalMoves()
在环境 class 中?更准确地说,是不是 必须在此 class 中具有与每个对应的方法 来自 Animal 接口的方法?
非常感谢!
它具有 Bridge 模式的结构,因为它具有模式中典型的那种 class 关系和方法。我不确定您示例的语义是否适合这种模式。此模式的主要要点是您有一个使用一个或多个 实现 class 的 class。你会说你的
Animal
classes 提供Environment
的实现吗?是的,你确实可以使用抽象classes。请记住,设计模式是典型的语言不可知论者。在某些语言中,例如 C++,接口是使用包含纯抽象方法的 classes 创建的,因为与 Java 不同,C++ 中没有用于接口的特定关键字。图中的标签 "interface" 表示概念意义上的接口,而不是实际的 Java 关键字。事实上,您甚至可以使用具体的 class 作为您的实现者,尽管使用接口通常是一种很好的做法,因为它提供了更大的灵活性。
不,没有必要使用与实现者 classes 完全相同的方法。实现者 classes 提供了许多被其他 class 使用的实现方法。它如何使用它们取决于 class 想要提供的功能。
Bridge 模式在其他语言中更有用,例如 C++,它被称为 "pImpl idiom" 或 "opaque pointer",因为它可以用来对用户隐藏实现:他们不能查看有关实施的任何信息 class。在Java中,这种隐藏是不可能的。
- 您展示的领域(动物及其环境)并不是桥接模式的良好用例。它有一个非常具体的目的:将抽象(包括该抽象的扩展)与实现(同样可能包括扩展)分开。关键特征之一是抽象引用实现(名称中的 'bridge')而不是扩展或实现抽象的实现。一般具体实施由客户在运行-时间决定。
很难想到模拟真实世界对象(如动物和环境)的桥梁的自然用例。更容易想到旨在执行某些功能的 class。
// abstraction
abstract class Logger {
protected final LogOutputter outputter;
public abstract void log(String message);
}
// abstraction extension
class ErrorLogger extends Logger {
public void log(String message) {
outputter.output("Error: " + message);
}
}
// implementation interface
interface LogOutputter {
void output(String message);
}
// implementation extensions
class FileLogOutputter implements LogOutputter ...
class ConsoleLogOutputter implements LogOutputter ...
客户可能会做类似的事情:
Logger logger = new ErrorLogger(new FileLogOutputter("errors.log"));
我建议我在此示例中使用的 class / 接口组合非常典型。您可以进行抽象和接口,但考虑到桥接点是引用实现,因此更容易使其成为抽象 class.
希望这个例子也能回答这个问题:你可以在抽象和实现中有类似的方法,但这当然不是必需的。该模式有趣且有用的方面之一是不同的独立特征(在本示例中,记录的内容和记录方式)可以单独定义为抽象和实现的扩展。这使您可以混合和匹配特征,而不会出现 class 结构失控的情况。这些特性的独立性(即正交性)往往会要求两种结构中的方法完全不同。