mardi 30 novembre 2021

Identifying code smells in the classes which represent a protoype for a facebook

Consider the following two classes:

public class Person<P extends Comparable<P>> {
    
    private List<Person<P>> following = new ArrayList<Person<P>>();
    private List<Person<P>> friends = new ArrayList<Person<P>>();
    private P id;

    public Person(P id) {
        this.id = id;
    }

    public P getId() {
        return id;
    }

    public List<Person<P>> getFollowing() {
        return following;
    }

    public List<Person<P>> getFriends() {
        return friends;
    }
    
    public boolean isFollowing(Person<P> person) {
        return following.contains(person);
    }


    public void addFriend(Person<P> person) {
        friends.add(person);
    }
}

public class WasteBookController<P extends Comparable<P>> {
    
    List<Person<P>> people = new ArrayList<Person<P>>();
    /**
     * Adds a new member with the given name to the network. 
     */
    public void addPersonToNetwork(P name) {
        people.add(new Person<P>(name));
    }

    /**
     * @preconditions person1 and person2 already exist in the social media network.
     * person1 follows person2 in the social media network.
     */
    public void follow(P person1, P person2) {
        if (person1.equals(person2)) {
            return;
        }

        for (Person<P> member1 : people) {
            if (member1.getId().equals(person1)) {
                for (Person<P> member2 : people) {
                    if (member2.getId().equals(person2)) {
                        List<Person<P>> following = member1.getFollowing();
                        following.add(member2);

                        if (member2.isFollowing(member1)) {
                            member1.addFriend(member2);
                            member2.addFriend(member1);
                        }
                    }
                }
            }
        }
    }

    public int getPopularity(P person) {
        Person<P> member = people.stream().filter(p -> p.getId().equals(person)).findFirst().get();
        int popularity = 0;

        for (Person<P> other : people) {
            List<Person<P>> following = other.getFollowing();
            if (following.contains(member)) {
                popularity += 1;
            }
        }

        return popularity;
    }

    public int getFriends(P person) {
        Person<P> member = people.stream().filter(p -> p.getId().equals(person)).findFirst().get();
        return member.getFriends().size();
    }

    /**
     * Returns an iterator to the network (each member)
     * ordered by the given parameter.
     */
    public NetworkIterator<P> getIterator(String orderBy) {
        Comparator<Person<P>> comparator = null;
        if (orderBy.equals("popularity")) {
            comparator = Comparator.comparing(p -> -getPopularity(p.getId()));
        } else if (orderBy.equals("friends")) {
            comparator = Comparator.comparing(p -> -getFriends(p.getId()));
        }

        comparator = comparator.thenComparing(Person::getId);

        return new NetworkIterator<P>(people.stream()
                     .sorted(comparator)
                     .map(Person::getId)
                     .collect(Collectors.toList())
                     .iterator());
    }

    public void switchIteratorComparisonMethod(NetworkIterator<P> iter, String orderBy) {
        // TODO Part d)
    }
}

I want to identify if there are any design issues or code smells in this?
It's like a backend implementation for a Facebook where people can have followers and friends
A person cannot follow itself, and if a person1 follows person2 and person2 follows person1, they are friends.
I am looking for some ways to improve it. P extends Comparable

- Since I want the IDs to be comparable, I did this. But I am not sure if this is a perfect way

Aucun commentaire:

Enregistrer un commentaire