I've got a question about the repetition of classes between modules.
I had a large module with 24 classes and divide it into three classes with 8. But there is a class ("users") who appears in two of the modules. I can repeat it? And I need to put the attributes in both modules?
And what is the maximum ideal for classes in a module?
Practically speaking: In UML, you do can describe a class / or object many times. And, you don't have to show all members (properties).
The ideal way to describe classes & relationships, is that each class is contained by a package, but, can be referenced (have some kind of relation) with other classes, either in the same package or different package.
The following diagrams are, in practical terms ok, and are several ways to describe the same thing in U.M.L. Im trying not to confuse you, with many diagrams.
The whole idea, is that in U.M.L, you may have several choices to describe or model the same idea.
Fig 1. Example fully described classes within same package.
...................................................................................
..+--------------------+...........................................................
..|..Streams...........|...........................................................
..+--------------------+---------------------------------------------------------+.
..|..............................................................................|.
..|.+----------------------------------+....+----------------------------------+.|.
..|.| StreamClass |....| ReaderClass |.|.
..|.+----------------------------------+....+----------------------------------+.|.
..|.| [#] void Read() <<abstract>> |....| [+] void Read() <<override>> |.|.
..|.| [#] void Write() <<abstract>> +<---+ [+] bool CanRead() <<override>> |.|.
..|.| [+] bool CanRead() <<virtual>> |....| [+] bool CanWrite() <<override>> |.|.
..|.| [+] bool CanWrite() <<virtual>> |....| [+] bool CanRead() <<virtual>> |.|.
..|.+----------------------------------+....+----------------------------------+.|.
..|..............................................................................|.
..+------------------------------------------------------------------------------+.
...................................................................................
Fig 2. Example classes within same package, omitting unnecesary members
....................................................................................
..+--------------------+............................................................
..|..Streams...........|............................................................
..+--------------------+----------------------------------------------------------+.
..|...............................................................................|.
..|.+----------------------------------+....+----------------------------------+..|.
..|.| StreamClass |....| ReaderClass |..|.
..|.+----------------------------------+....+----------------------------------+..|.
..|.| [#] void Read() <<abstract>> |....| [+] void Read() <<override>> |..|.
..|.| [#] void Write() <<abstract>> +<---+ [+] bool CanRead() <<override>> |..|.
..|.| [+] bool CanRead() <<virtual>> |....| [+] bool CanWrite() <<override>> |..|.
..|.| [+] bool CanWrite() <<virtual>> |....+----------------------------------+..|.
..|.+----------------------------------+..........................................|.
..|...............................................................................|.
..+-------------------------------------------------------------------------------+.
....................................................................................
Fig 3. Example classes in different packages
...................................................................................
.+--------------------+...................+--------------------+...................
.|..Streams...........|...................|..Readers...........|...................
.+--------------------+-----------------+.+--------------------+-----------------+.
.|......................................|.|..|...................................|.
.|.+----------------------------------+.|.|.+----------------------------------+.|.
.|.| StreamClass |.|.|.| ReaderClass |.|.
.|.+----------------------------------+.|.|.+----------------------------------+.|.
.|.| [#] void Read() <<abstract>> |.|.|.| [+] void Read() <<override>> |.|.
.|.| [#] void Write() <<abstract>> +<----+ [+] bool CanRead() <<override>> |.|.
.|.| [+] bool CanRead() <<virtual>> |.|.|.| [+] bool CanWrite() <<override>> |.|.
.|.| [+] bool CanWrite() <<virtual>> |.|.|.+----------------------------------+.|.
.|.+----------------------------------+.|.|......................................|.
.|......................................|.|......................................|.
.+--------------------------------------+.+--------------------------------------+..
...................................................................................
Sometimes, packages, are omitted in the class diagrams, or are consider to be in the same package.
Fig 4. Example fully described classes without packages.
................................................................................
..+----------------------------------+....+----------------------------------+..
..| StreamClass |....| ReaderClass |..
..+----------------------------------+....+----------------------------------+..
..| [#] void Read() <<abstract>> |....| [+] void Read() <<override>> |..
..| [#] void Write() <<abstract>> +<---+ [+] bool CanRead() <<override>> |..
..| [+] bool CanRead() <<virtual>> |....| [+] bool CanWrite() <<override>> |..
..| [+] bool CanWrite() <<virtual>> |....+----------------------------------+..
..+----------------------------------+..........................................
................................................................................
And, finally, sometimes each class is fully described with its container packaged, plus a diagram, where only relations are displayed. The next 3 figures represent 3 complementary diagrams.
Fig 5.1 Single class example.
...........................................
..+--------------------+...................
..|..Streams...........|...................
..+--------------------+-----------------+.
..|......................................|.
..|.+----------------------------------+.|.
..|.| StreamClass |.|.
..|.+----------------------------------+.|.
..|.| [#] void Read() <<abstract>> |.|.
..|.| [#] void Write() <<abstract>> |.|.
..|.| [+] bool CanRead() <<virtual>> |.|.
..|.| [+] bool CanWrite() <<virtual>> |.|.
..|.+----------------------------------+.|.
..|......................................|.
..+--------------------------------------+.
...........................................
Fig 5.2 Single class example.
...........................................
..+--------------------+...................
..|..Readers...........|...................
..+--------------------+-----------------+.
..|......................................|.
..|.+----------------------------------+.|.
..|.| ReaderClass |.|.
..|.+----------------------------------+.|.
..|.| [#] void Write() <<abstract>> |.|.
..|.| [#] void Read() <<override>> |.|.
..|.| [+] bool CanRead() <<override>> |.|.
..|.| [+] bool CanWrite() <<override>> |.|.
..|.+----------------------------------+.|.
..|......................................|.
..+--------------------------------------+.
...........................................
Fig 5.3 Example Relations among classes.
................................................................................
..+----------------------------------+....+----------------------------------+..
..| StreamClass +<---+ ReaderClass |..
..+----------------------------------+....+----------------------------------+..
................................................................................
Summary
Remember that U.M.L. is a guide, not an strict path.
Cheers.
Good answer UMLcat. UML can reuse the same classifiers in more than one class diagram. I mean that for many years UML was related to graphical views and sometimes inside the same view all the project classifiers.
The UML metamodeling approach is to simply create an UML model which is live synchronized with the diagrams. In many tools you have mappers between graphical presentation and model. For example with Eclipse you have the graphical mapper GMF which call the model mapper EMF which then create an UML model. It is therefore impossible to live synchronized the UML view with the uml model stored on your hard disk in xmi format.
Omondo EclipseUML have launched this metamodedl initiative few year ago. It allows you to create as many diagrams which are live synchronized with your UML model on disk saved immediately into XMI UML 2.3 format. You can therefore reuse the same classifier in different views because all the model logic is in the modedl saved on disk and live synchronize.
The round trip engineering is not only between code and model but deeper between model and metamodel. It gives full power to UML !!
Related
I am currently using the ExtentReport framework to generate a comprehensive test report after TestNG completes its suite of test class using Selenium.
To make the process easier and to reduce code, I am using a listener class to automate the Test Success and Test Failure scenerios such that in case of every success/failure, there will some actions done to the report automatically. The listener implementation goes like this:
public class Listeners extends Base implements ITestListener{
ExtentTest test;
ExtentReports extent=ExtentReporterNG.getReportObject();
**ThreadLocal**<ExtentTest> extentTest =new **ThreadLocal**<ExtentTest>();
public void onTestStart(ITestResult result) {
// TODO Auto-generated method stub
test= extent.createTest(result.getMethod().getMethodName());
extentTest.set(test);
}
public void onTestSuccess(ITestResult result) {
takeScreenShotandAttachtoReport();
extentTest().get().log("Success");
}
public void onTestFailure(ITestResult result) {
takeScreenShotandAttachtoReport();
extentTest().get().log("Failure");
}
public void onFinish(ITestContext context) {
// TODO Auto-generated method stub
extent.flush();
}
As above, with every test case, an ExtentTest ThreadLocal would be instantiated along the interface methods, which would execute with respect to their individual listeners based on the test results. This reduces the extra code that are needed for the same implementation if ExtentReport was to be instantiated on every test class. However, this implementation has its own hurdle: It would not allow variations (logging, individual test result customization, etc). Say I'd want some ExtentReport logging to be done for each unique test case, I have no ways to invoke the listener and do any type of logging for that particular test.
Is there anyway that this can be solved?
I am trying to intercept or advice constructor invocation as following:
new AgentBuilder.Default()
//.disableClassFormatChanges()
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
.with(AgentBuilder.TypeStrategy.Default.REDEFINE)
.type(ElementMatchers.nameMatches("org.openqa.selenium.firefox.FirefoxDriver"))
.transform((builder, typeDescription, classLoader, module) -> builder
.constructor(ElementMatchers.any())
.intercept(SuperMethodCall.INSTANCE.andThen(MethodDelegation.to(FirefoxDriverInterceptor.class))))
//.intercept(SuperMethodCall.INSTANCE.andThen(Advice.to(FirefoxDriverConstructorAdvice.class))))
Interceptor:
#RuntimeType
public static void intercept(#Origin Constructor<?> constructor) {
System.out.println("Intercepted: " + constructor.getName());
}
Advice:
#Advice.OnMethodExit
public static void after(//#Advice.This Object thisObject,
#Advice.Origin String method,
#Advice.AllArguments Object[] args
) {
logger.info("<----- instantiated firefoxwebdriver: {}", method);
}
on trying with interceptor or advice, exception throws is:
java.lang.IllegalStateException: Cannot call super (or default) method for public org.openqa.selenium.firefox.FirefoxDriver(org.openqa.selenium.firefox.GeckoDriverService,org.openqa.selenium.Capabilities)
at net.bytebuddy.implementation.SuperMethodCall$Appender.apply(SuperMethodCall.java:102)
at net.bytebuddy.implementation.bytecode.ByteCodeAppender$Compound.apply(ByteCodeAppender.java:134)
Let me know for nay pointers. Thank you for your help.
You are blending Advice and MethodDelegation here which are not related. They have some common concepts, but you cannot mix the annotations.
You can however wrap advice around a delegation:
Advice.to(...).wrap(MethodDelegation.to(...))
In my JUnit tests, I need to override some public method behavior from class A (module M1). For that, I am doing something similar to that (in JUnit module M2):
package com.acme;
public class B extends A{
#Override
public String methodToOverride(){
return "TestDataHere";
}
}
How Java 9 JPMS recommended to override some package in 3rd party module or your module? How to properly configure to JPMS to use modules M1 and M2 with the same package names?
I have been using TestNG and having problems with two annotations, #BeforeTest and #BeforeClass. I would like to know if both are applied which will run first ?
Answer: Method annotated with #BeforeTest will be invoked before than the method annotated with #BeforeClass.
TestNG annotations execution order in reference to #Test and description:
#BeforeSuite: The annotated method will be run before all tests in
this suite have run.
#BeforeTest: The annotated method will be run before any test method belonging to the classes inside the
tag is run.
#BeforeGroups: The list of groups that this
configuration method will run before. This method is guaranteed to
run shortly
before the first test method that belongs to any of these groups is
invoked.
#BeforeClass: The annotated method will be run before the first test method in the current class is invoked.
#BeforeMethod: The annotated method will be run before each test method.
#Test: The test method or class
#AfterMethod: The annotated method will be run after each test method.
#AfterClass: The annotated method will be run after all the test methods in the current class have been run.
#AfterGroups: The list of groups that this configuration method will run after. This method is guaranteed to run shortly
after the last test method that belongs to any of these groups is
invoked.
#AfterTest: The annotated method will be run after all the test methods belonging to the classes inside the tag have
run.
#AfterSuite: The annotated method will be run after all tests in this suite have run.
There are various other annotations provided by TestNG and different
types of attributes/parameters can be passed to these annotations. For
more information on TestNG annotations follow this link
Annotations execution order:
BeforeSuite
BeforeTest
BeforeClass
BeforeMethod
Test
AfterGroups
AfterClass
AfterTest
You can check with the pseudo code:
public class TestAnnotationsPriorityOrder {
public int i=0;
#BeforeSuite
public void beforeSuite(){
i++;
System.out.println(i+"::BeforeSuite");
}
#AfterSuite
public void afterSuite(){
i++;
System.out.println(i+"::AfterSuite");
}
#BeforeTest
public void beforeTest(){
i++;
System.out.println(i+"::BeforeTest");
}
#AfterTest
public void afterTest(){
i++;
System.out.println(i+"::AfterTest");
}
#BeforeGroups
public void beforeGroups(){
i++;
System.out.println(i+"::BeforeGroups");
}
#AfterGroups
public void afterGroups(){
i++;
System.out.println(i+"::AfterGroups");
}
#BeforeClass
public void beforeClass(){
i++;
System.out.println(i+"::BeforeClass");
}
#AfterClass
public void afterClass(){
i++;
System.out.println(i+"::AfterClass");
}
#BeforeMethod
public void beforeMethod(){
i++;
System.out.println(i+"::BeforeMethod");
}
#AfterMethod
public void afterMethod(){
i++;
System.out.println(i+"::AfterGroups");
}
#Test
public void TestMethod(){
i++;
System.out.println(i+"::Test");
}
}
Before test first and then before class.
#BeforeTest: The annotated method will be run before any test method belonging to the classes inside the <test> tag is run.
#BeforeClass: The annotated method will be run before the first test method in the current class is invoked.
http://testng.org/doc/documentation-main.html#annotations
I am finding it difficult to model polymorphism and instances in UML.
For example if i have an abstract, parent or base class called "Bird", i would imagine that you could say that "duck" is one form of polymorphism but it could also be an instance.
Maybe, i'm confusing where one starts and ends. Are there visual examples of these?
It is simple enough.
If one concrete class Cage has reference to abstract class Bird, and concrete classes Woodpecker and Canary are derived from the last, this is polymorphism. You'll have to choose what bird really will sit in the cage, for abstract class has no instances. The same for Interface.
The question of inheritance vs instance depends on functionality. If there are any differences in your data model between ducks and other types of birds then you would want a Duck class that inherits from Bird. Otherwise you're looking at your duck simply as an instance of Bird.
Polymorphism only comes into play when you are calling the same method across different Bird implementations.
For UML modeling here are a couple points to help you out.
This book is required reading for many Software Engineeing courses and has served me well for many years.
http://www.amazon.com/UML-Distilled-Standard-Modeling-Language/dp/0321193687
This blog does a pretty good job of showing the different use cases and the corresponding OOP models. http://usna86-techbits.blogspot.com/2012/11/uml-class-diagram-relationships.html
First, I think that your question is how to model polymorphism. To illustrate, see these Java codes:
Drawable.java
package examples.simple.model;
public interface Drawable {
public void draw();
}
Shape.java
package examples.simple.model;
public abstract class Shape implements Drawable {
private Point center;
public Point getCenter() {
return center;
}
public void setCenter(Point center) {
this.center = center;
}
}
Rectangle.java
package examples.simple.model;
public class Rectangle extends Shape {
public void draw() {
System.out.println("Drawing a rectangle....");
}
}
Circle.java
package examples.simple.model;
public class Circle extends Shape {
public void draw() {
System.out.println("Drawing a circle....");
}
}
Line.java
package examples.simple.model;
public class Line implements Drawable{
public void draw() {
System.out.println("Drawing a line");
}
}
Plotter.java
package examples.simple.client;
import java.util.ArrayList;
import java.util.List;
import examples.simple.model.Circle;
import examples.simple.model.Drawable;
import examples.simple.model.Rectangle;
import examples.simple.model.Shape;
import examples.simple.model.Line;
class Plotter {
public static void main(String[] args) {
List<Drawable> drawables = new ArrayList<Drawable>();
Shape s = new Circle();
drawables.add(s);
s = new Rectangle();
drawables.add(s);
Line l = new Line();
drawables.add(l);
for (Drawable drawable : drawables) {
drawable.draw();
}
}
}
These are a classical example of polymorphism. The class diagram is
In this situation, using a sequence diagram, the polymorphic invocations are modeled by multiples scenarios controlled by the guard conditions. Therefore, for each polymorphic scenario, the dynamic binding (polymorphic invocation) is represented for a "scenario box". So, this is a single model (sequence diagram) to show polymorphic invocations.
Finally, representing polymorphic invocations using UML is actually a challenge.