你能解释一下OOP的混乱吗?

时间:2015-12-23 12:59:59

标签: class oop object

我正在创建一个测试网站的程序。网站有一个注册过程,我正在测试。

我创建了一个名为“Client”的类,它应该存储有关客户端的信息(姓名,姓氏,电子邮件等)。

由于我正在测试,我使用随机数生成器为客户端生成一个名称(我有一个名称列表,其中一个是随机选择的。)

显然,我应该创建一个方法“generateName()”。

但问题是:我应该在哪个班级创建它?

许多程序员会在Client类中创建该方法。并会做那样的事情:

client = new Client ();
client.generateName ();

但我已经读过,这种方法不正确 - 因为客户端不为自己生成名称。程序确实。

根据这些信息,我这样做:

class Program
{
    private void generateName ();
}
...
class Client 
{
...
    public void name ( String name )
    {
        this.name = name;
    }
}

program = new Program ();
program.launch();

client = new Client ();
client.name ( program.generateName () );

但据我所知,开发人员并没有使用这种方法。

你能澄清一下,如何在这里知道“什么是对的,什么是错的”?对于这种情况,我应该使用哪些信息来源作为任意信息?

3 个答案:

答案 0 :(得分:0)

听起来generateName()可能是Client中的静态方法,因为它独立于实例:

class Client {
    private String name;

    public Client(String name) {
        this.name = name;
    }

    public static String generateRandomName() {
        String generatedName = ...;

        return generatedName;
    }
}

你可以简单地将它的值传递给当前的Client对象,或者通过构造函数传递:

client = new Client(Client.generateRandomName());

否则,我建议ClientNameGenerator处理名称生成,与SRP保持内联并提升cohesion。这将是更好的选择,看看您将来可能需要更多的名称生成方法:

class ClientNameGenerator {
    public String generateRandomName() {
        String generatedName = ...;
        return generatedName;
    }

    //other name generation methods...
}

您现在可以使用ClientNameGenerator对象来管理客户端名称的生成:

ClientNameGenerator nameGenerator = new ClientNameGenerator();

client = new Client(nameGenerator.generateRandomName());

只要您需要生成名称,只需使用您创建的ClientNameGenerator对象。

答案 1 :(得分:0)

有许多地方可能是此功能的合适位置。

您可以将它作为Client类的私有方法,由静态工厂方法用于生成具有随机名称的客户端。

public class Client {
    ....

    public static Client randomlyNamed() {
        return new Client(randomName());
    }

    private static String randomName() {
        return ...;
    }
}

但是私有方法可能更好地提取到更合适的类来生成随机字符串......

public class Client {
    private static final int defaultNameLength = 8;
    ....

    public static Client randomlyNamed() {
        return new Client(Strings.randomString(defaultNameLength));
    }
}

public class Strings
    private static String randomString(int length) {
        return ...;
    }
}

然后,您可以将静态方法扩展为通用的ClientBuilder类,其实例方法的名称类似于' withRandomName()'。

public class Client {
    ...
}

public class ClientBuilder {
    private static final int defaultNameLength = 8;
    ...

    public ClientBuilder randomlyNamed() {
        this.name = Strings.randomString(defaultNameLength);
    }

    public Client build() {
        return new Client(name);
    }
}

public class Strings
    private static String randomString(int length) {
        return ...;
    }
}

另一种方法是实现NamingStrategy(例如``)对象,该对象被赋予ClientBuilder对象。

public class RandomNames implements NamingStrategy {
    private static final int defaultNameLength = 8;
    public String name() {
        return String.randomString(defaultNameLength);
    }
}


public class ClientBuilder {
    private final NamingStrategy nameSource;
    public ClientBuilder(NamingStrategy nameSource) {
        this.nameSource = nameSource;
    }

    public Client build() {
        return new Client(nameSource.name());
    }
}

答案 2 :(得分:0)

纯粹的方法是拥有一个单独的ClientGenerator类来生成客户端。由于生成客户端不是典型的客户端行为,因此在您的应用程序模型中,客户端只不过是客户端属性的被动数据容器。但是,生成客户端是客户端域中的活动"。因此,创建一个静态方法Client.NewClient()是可以防御的,就像.NET feamework与Guid一样。另一方面,要生成guid的本质,它不代表现实世界中的某些东西。它是一个可生成的id。因此,这种比较可能不是完全相同的。

一个常见的类似错误(或者你想要的杂质)是对象上的Save方法。相反,应该有一个Persister类来完成这项工作。或经理。因为Save是你可以对班级做的事情,而不是班级的行为。