http://www.aspectprogrammer.org/blogs/adrian/2004/05/person_owns_dog.html

实际上,我一直在找寻这样的一个例子来说明类的应该就是一个独立的个体,不应该其他无关系的类有联系,今天看到这篇文章,一句话:正和我意!

Person owns Dog...

May 28, 2004

There's a famous OO problem involving people and dogs that I first learnt about in Meilir Page-Jones' excellent book "Fundamentals of Object-Oriented Design in UML." It involves a class Person, with an attribute numOfDogsOwned and a simple accessor method getNumDogsOwned(). The argument goes that this may not neccessarily be good design, since Person and Dog are distinct concepts, and dog ownership is not an essential property of being a person.

Page-Jones calls this mixed-role cohesion, and he explains the problem better than I can: "What if you wanted to reuse Person in an application that had no dogs? You could do so, but you'd have extra, useless baggage from the class, and you might get some pesky warnings about missing dogs from your compiler (or linker). And where should we stop with this design philosophy? Why not include these attributes in Person: numOfCarsOwned, numOfBoatsOwned, numOfCatsOwned, numOfFrogsOwned,... ?"

It's an interesting problem, because there's no perfect solution in OO - Page-Jones discusses the pros and cons of four possible solutions including just adding the members directly to Person, using a PersonDogOwnership relationship class, using an abstract mix-in class, and using aggregation. Mixed-role cohesion sounds like the kind of problem that inter-type declarations in AspectJ should be able to help us address, so here's the world's first (AFAIK) aspect-oriented solution to the person-owns-dog problem:

/** * not a dog in sight... */ public class Person { private String lastName; private Address address; ... public String getLastName() { return lastName; } ... }

Some of you will have heard me use my adverb/adjective analogy for aspects before, and that's exactly what we've got here. We want to create a dog-owning person, which we could do by creating a DogOwningPerson class (a bit like creating a new noun), but dog-owning isn't limited to people, maybe an Organisation can own dogs too? What we've got is a concept (a compound adjective, dog-owning) that stands in its own right independent of any one class, and that could be applied to many different classes. I'm thinking interface, and I'm thinking aspect...

/** * not a person in sight... */ public aspect DogOwnership { public interface IDogOwner {}; private int IDogOwner.numDogsOwned; public int IDogOwner.getNumDogsOwned() { return numDogsOwned; } }

This aspect represents in a single module the concept of dog ownership. It defines an IDogOwner interface (it doesn't have to be an inner-interface, but making it so helps to keep the whole thing together), and uses inter-type declarations to define a numDogsOwned attribute and a getNumDogsOwned() method on behalf of all dog owners.

We still haven't quite got to person-owns-dog - I wanted to keep the concept of dog ownership independent of any one kind of dog owner. If we have an application where we need person-owns-dog, we can write the following:

public aspect PersonOwnsDog { declare parents : Person implements DogOwnership.IDogOwner; }

I like this solution because Person and DogOwnership are independently reusable, and represent cohesive abstractions in their own right. The PersonOwnsDog aspect that binds the two together is also very clear and simple.

With these aspects in place, you could call the getNumDogsOwned method on a Person as follows:

Person person = new Person(); person.getNumDogsOwned();

this will compile happily and execute without any problems. If ever you build the application without the PersonOwnsDog aspect though, you'll get a compile-time error about missing dogs. If you don't want that to happen, you could code the client this way (and I probably would in this particular circumstance):

... if (person instanceof DogOwnership.IDogOwner) { ((DogOwnership.IDogOwner)person).getNumDogsOwned(); } ...

but it's just a matter of personal taste, the compiler doesn't require it.

Posted by adrian at May 28, 2004 12:21 PM [permalink]

转载于:https://www.cnblogs.com/Dabay/archive/2006/10/17/PersonOwnsDog.html

Person owns Dog...相关推荐

  1. Python 迁移学习实用指南:1~5

    原文:Hands-On Transfer Learning with Python 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自[ApacheCN 深度学习 译文集],采用译后编辑(MT ...

  2. 定义一个DOG类(Java)

    class Dog{String name;String color;int age;public Dog(String name,String color,int age){System.out.p ...

  3. matlab 双边沿滤波,图片漫画效果(DoG算子和双边滤波)

    对比下面两张图(从 http://hi.baidu.com/cwyalpha/blog/item/647745a9f33570f61e17a235.html 里翻出来的..),漫画有3个特点: 1.边 ...

  4. SIFT中LoG和DoG比较

    在实际计算时,三种方法计算的金字塔组数noctaves,尺度空间坐标σ,以及每组金字塔内的层数S是一样的.同时,假设图像为640*480的标准图像. 金字塔层数: 其中o_min = 0,对于分辨率为 ...

  5. SIFT原理与源码分析:DoG尺度空间构造

    <SIFT原理与源码分析>系列文章索引:http://blog.csdn.net/xiaowei_cqu/article/details/8069548 尺度空间理论 自然界中的物体随着观 ...

  6. 打印dog信息java_java – 打印arraylist元素?

    要打印整个列表还是要遍历列表的每个元素?无论哪种方式打印任何有意义的Dog类需要从Object类覆盖toString()方法(如其他答案中所述),以返回有效的结果. public class Prin ...

  7. python定义一个dog类 类属性有名字毛色体重_面向对象实践,练习,Python

    1.定义一个汽车类(Car),属性有颜色,品牌,车牌号,并实例化两个对象 2.定义一个球员类(Player),属性有身高.体重.姓名,实例化两个球员,分别是姚明和科比 3.定义一个僵尸类(Zombie ...

  8. 【图像】Dog(高斯差分)检测角点

    DoG (Difference of Gaussian)是灰度图像增强和角点检测的方法,其做法较简单,证明较复杂,具体讲解如下: Difference of Gaussian(DOG)是高斯函数的差分 ...

  9. 看门狗(Watch Dog)是嵌入式系统中一种常用的保证系统可靠性的技术,()会产生看门狗中断。【详细!小白也能看懂!】

    看门狗(Watch Dog)是嵌入式系统中一种常用的保证系统可靠性的技术,()会产生看门狗中断. A. 软件喂狗 B. 处理器温度过高 C. 外部中断 D. 看门狗定时器超时 解析: 思考方式: 每个 ...

最新文章

  1. Centos 7 让docker飞一会儿
  2. 非视线成像 - 把墙角变为相机
  3. linux io函数,Linux下普通IO文件操作函数---C语言
  4. matlab中基本函数的用法
  5. 阶段1 语言基础+高级_1-2 -面向对象和封装_18定义一个标准的类
  6. asc desc排序_21.数据库排序?左连接 ?右连接?
  7. 飞鸽传书2012软件设计者的角度来看
  8. Arduino笔记-外部中断实验(震动传感器实时亮灯)
  9. python-类的装饰器-主要给类添加属性用途
  10. c 语言程序上机考试系统,计算机二级C语言上机考试操作步骤及流程
  11. 自动编译 打包 签名 android程序
  12. (VBA) Get String
  13. ActivityManagerService启动过程
  14. 熬夜总结的2022java面试题
  15. miui7 android系统版本,miui7系统
  16. 小米商城app端项目
  17. 上官婉儿飞天连招(玩法解析)
  18. ubuntu 下搭建gitLab
  19. nn.Linear()函数详解
  20. 【漫漫转码路】Day 38 C++ day09

热门文章

  1. XPS如何在线转Word格式
  2. Word目录中自动添加自定义样式的多级标题的方法
  3. 产品经理的工资为什么这么高?背后的逻辑是什么?
  4. CentOS 7下的软件安装方法及策略
  5. 如何解决Kettle读取txt文件时出现的中文乱码问题?
  6. 数据结构与算法真的那么重要么?
  7. java ffmpeg 合并视频_ffmpeg 合并拼接 mp4视频
  8. MATLAB数学建模 回归与内插
  9. MinIO客户端mc基础命令学习
  10. yolov5 nms 源码理解