• Person owns Dog...


    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]

  • 相关阅读:
    最全的静态网站生成器(开源项目)
    移动互联网流量变现模式调研问卷
    公众平台商户接入(微信支付)功能申请教程
    微信支付全面开放
    百度天气预报接口
    微信公众平台开发(83) 生成带参数二维码
    微信支付接口申请指南
    微信自媒体账号涉违规大规模被封
    php大文件上传解决方案支持分片断点上传
    html5大文件上传解决方案(500M以上)
  • 原文地址:https://www.cnblogs.com/Dabay/p/PersonOwnsDog.html
Copyright © 2020-2023  润新知