Generation and Handcoding

Werbung
Farbe!
Generative
Software
Engineering
3. Integrating Handwritten Code
Prof. Dr. Bernhard Rumpe
Software Engineering
RWTH Aachen University
http://www.se-rwth.de/
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Generation and Handcoding
Page 2
 Not everything shall and can be generated
• Code is fine, when model would not be more abstract
 How to integrate hand written code with generated code
• General principles
• How they apply in DEX
hand
written code
Parameterized
generator
Generator script/template
Map: concept
code
API
generated code
+ included parts
components
components
components
API
model
Predefined
Predefined
Predefined
runtime system
Environment: hardware, GUI, frameworks
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Goals of Handcoding
Page 3
 The goal of handcoding
• extend domain model
• add functionality to generated code
• customize generated code
 Benefits of handcoding
• Normally re-generation is not needed
• Reuse of existing handwritten code
• Tooling (e.g. editor) for the programming language can be used
 DEX supports extensions for
• domain model with attributes and method bodies
• domain model with signatures
• generated GUI code
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Handwritten Code
Page 4
 Handcoding (HC) = the process of writing code manually (by hand)
 vs. generating code (GC), where the code comes from the generator.
 Important questions to decide:
• Artefacts of interest for users?
• What to write, what to read and understand
• Generating and handcoding in which order?
• Repeatable generation?
• Dependences between the forms of code?
• Methodical alignment
• Which knowledge is necessary for
• the developer
• the generating tool
• the compiler, linker and Java virtual machine
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Mixing of HC and Generation in Artifacts
Page 5
 Scenario A:
• 1. Let the generator produce code frames in files
• 2. Add code manually, e.g. method implementations
 Advantage:
• HC is well integrated inside GC
 Disadvantage:
• “One shot” generation only
• Model becomes irrelevant because useless after generation,
• Changes in models impossible
• Doesn’t support evolution
 Decision:
• Strict separation of handcoding and generation on artifacts!
• Each artifact (= file) is either handcoded or generated.
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Mixing of HC and Generation in Artifacts -2
Page 6
 Scenario B:
• 1. Let the generator produce code frames in files
• Generate explicit markers to protect regions of HC
• 2. Add code manually in protected regions
 Advantage:
• Easy to use and easy to identify where to handcode
 Necessary:
• Extraction of HC for inclusion in next generation step
 Disadvantages:
• Not robust e.g. against editing
• Vulnerable against advanced tools (e.g. beautifiers)
• No clean full generation possible
• Generated code needs to be version controlled
public class Person {
public String getFullname () {
/* [protected GEN#XwgHEge23qp (method getFullname)] */
// to be handcoded
/* [/protected GEN#XwgHEge23qp] */
} }
Java
«gen»
«hc»
«gen»
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Separation of HC and GC in Artifacts
Page 7
 Each artifact (file) is either HC or GC.
 Advantages:
• Only sources (HC and models) need to be versioned
• this greatly reduces conflicts
• and helps understanding progress from the version control logs
• Developers normally don’t read generated code
• just understand the interfaces
• Clean & regenerate always works
 Necessary:
• HC needs to be written and integrated
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Alternatives for Integration of HC
Page 8
 1. Reference it from the model.
•  Ch. 2 for attributes &
• DEX would allow method signatures & bodies in a CD, but that
pollutes the CD (not recommended)
 2. Compiler: no that doesn’t work
• We would need “partial classes”, not provided by Java
 3. When starting at runtime
• 3a) Write your own main()-function and call HC to configure GC
• that is fine and actually used by many frameworks
• 3b) write static-code pieces: no, because classes are loaded lazy in
Java (and thus static code may be never called)
 4. Config file
• Works, but is error prone because it looses type safety.
 5. Generator identifies HC and integrates references to it
• HC to follow naming conventions to be identified
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Overview of Product with HC
Page 9
 Generated DEX product has this architecture
• HC internal architecture is out of generators control:
• But it is recommended to maintain the architecture
GUI
hand
coded
generated
RTE
standard
components
hand
coded
generated
RTE
standard
components
hand
coded
generated
RTE
standard
components
Application Core
Persistence
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Generator detects HC, the Principle:
Page 10
 Approaches DEX uses: (Placeholder X)
 1. Extending signature and implementation of domain class X.java
• When XSIG.java exists  inherit it in X.java
• When XEIMP.java exists  use it in the factory
(assuming it is a subclass of XIMP)
 2. Specific Hot Spots documented in the generator handbook.
 Extending signature, implementation and hot spots
• is based on naming conventions (e.g. XSIG, XEIMP)
Farbe!
Generative
Software
Engineering
3. Integrating Handwritten Code
3.1. Extension of Generated Code
Prof. Dr. Bernhard Rumpe
Software Engineering
RWTH Aachen University
http://www.se-rwth.de/
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Generated Artifacts in DEX
Page 12
 What DEX does:
 One class is mapped to
• an interface
• an implementation, and
• a factory for object creation
CD SocNet
class Group extends Profile
{ // …
String purpose;
}
«interface»
Group
+ String getPurpose();
+ void setPurpose(String s)
GroupImpl
Java
…
…
- String purpose;
+ String getPurpose();
+ void setPurpose(String s)
«gen»
GroupFactory
+static Group create()
#Group doCreate()
…
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Extending the Implementation
Page 13
 … and adapting generated functionality
 by defining HC class XEIMP that inherits GC
«gen»
«interface»
Group
«gen»
«gen»
GroupFactory
Product-CD
+static Group create()
#Group doCreate()
…
GroupImpl
«gen»
handcoded Java class
«hc»
GroupEIMP
import GroupEIMP; …
class GroupFactory …
protected Group doCreate() {
return new GroupEIMP();
}
 Generator adapts only the GroupFactory
• now GroupEIMP objects are created
 Necessary:
• GroupEIMP is subclass of GroupImpl
• “EIMP” was chosen to prevent occasional use
• “EIMP” = extended implementation
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
adapted Factory
How to add handcoded Java classes
Page 14
 Two steps are required to add handcoded Java classes in DEX
• 1. Create handcoded Java class GroupEIMP
• 2. Implement the full and the empty constructor of GroupImpl
Java
public class GroupEIMP extends GroupImpl {
public GroupEIMP() {
super();
}
«hc»
attributes of
class GroupImpl
protected GroupEIMP(String profileName,
boolean isOpen,
Date created,
String purpose) {
super(profileName, isOpen, created, purpose);
}
}
• (3. Override methods and add attributes/methods …)
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
How to add attributes to the domain model
Page 15
 The domain model can be extended by adding attributes
Java
public class GroupEIMP extends GroupImpl {
«hc»
private String newAttribute = "My String";
// ...
}
new domain
model attribute
 Properties of these attributes
• not visible in the GUI
• not saved in the database
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
How to add Methods
Page 16
 Application functionality can be extended by adding new methods
• This brings the “meat” to the application
Java
public class GroupEIMP extends GroupImpl {
// ...
public String groupOverview (){
return "Group Overview: " + getPurpose()
+ " " + getHeadcount();
}
}
 Limitations
• New methods do not appear in the signature of the
Group interface
«hc»
new method
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
How to implement derived Attributes
Page 17
 Derived attribute does have an empty default
implementation as get/retrieve-method
 Add meaning to the derived attribute
using HC by overriding the getter
public class GroupEIMP extends GroupImpl {
// ...
@Override
public int getHeadcount() {
return sizeMembers()+ sizeOrganizers();
}
}
 Every generated method can be overwritten
• Incl. ordinary get/setters for attributes
• Association methods
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
DEX Example for Derived Attributes
Page 18
 derived attributes are shown in the gui
Model-CD
Group
/int headcount;
…
Java
«hc»
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Overwriting Generated Methods
Page 19
 Generated methods can be adapted by HC
Java
Model-CD
Group
boolean isOpen
Date created
String purpose
/int headcount
overrride
«hc»
public class GroupEIMP extends GroupImpl {
//constructors ...
public void setPurpose(String pname) {
StatusBar.write("Group "+profileName
+" new purpose "+pname)
super.setPurpose(pname);
}
}
 Log result is shown in the bottom line on the GUI
Logging
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Extending the Implementation
Page 20
 Advantages:
• relatively little effort to adapt implementation
• adaptable reuse of generated implementation
• smooth integration of HC artefact
Product-CD
«gen»
«interface»
Group
«gen»
 Restriction:
• Only one subclass supported
GroupImpl
«hc»
GroupEIMP
 Disadvantages:
• IDEs don’t assist when superclass hasn’t been generated yet
• = many false errors are reported after fresh checkout or a clean
• some risk of unwanted occasional detection of “*EIMP”
• re-generation necessary after EIMP-class is created (or deleted)
to get adapted factory
Farbe!
Generative
Software
Engineering
3. Integrating Handwritten Code
3.2. Extending Data Model Signature
Prof. Dr. Bernhard Rumpe
Software Engineering
RWTH Aachen University
http://www.se-rwth.de/
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Extending the Signature of a Class
Page 22
 by defining HC interface XSIG that inherits to GC
Product-CD
«hc»
public interface GroupSIG {
String getFullname();
}
«interface»
GroupSIG
«gen»
 1. Generator detects XSIG.java
 2. Generated code is adapted to implement
the new interface
 3. Generator also expects XEIMP.java,
because XImpl is now abstract
«interface»
Group
«gen»
GroupImpl
«hc»
GroupEIMP
 Signature extensions (methods) are inherited
to interface X.java and handcoded in XEIMP.java
 “Sandwich”-Principle for extension
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
How to add signature extensions
Page 23
 Required steps
• 1. Add handwritten Java interface XSIG
• 2. Add handwritten Java class XEIMP
• 3. Implement new methods in XEIMP
Product-CD
«hc»
«interface»
GroupSIG
handwritten
Java interface
Java
«gen»
public interface Group extends dex.socnet.GroupSIG {
//...
}
public abstract class GroupImpl implements dex.socnet.Group
{
//...
}
«gen»
«interface»
Group
«gen»
GroupImpl
«hc»
GroupEIMP
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Mapping Model Inheritance and HC Extension
Page 24


Inheritance and implementation relation is preserved
DEIMP inherits CEIMP indirectly
through DImpl
Model-CD
interface A;
interface B;
class C implements A;
class D extends C implements B;
«interface»
ASIG
«interface»
CSIG
«interface»
A
«interface»
C
«interface»
BSIG
«interface»
DSIG
«interface»
B
«interface»
D
Product-CD
«gen»
«abstract»
CImpl
CEIMP
«abstract»
DImpl
DEIMP
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Signature Extensions Summary
Page 25
 Advantages
• Separation of generated and handwritten artifacts
• Signature extensions in HC interfaces
• Supports redefinition of generated functionality
• Supports implementation of internally available methods and
attributes
 Disadvantages/problems
• Signature of methods need to be repeated at implementation
• Re-generation is necessary when SIG/EIMP-class is added or
removed
Farbe!
Generative
Software
Engineering
3. Integrating Handwritten Code
3.3. Hot Spots for the DEX GUI
Prof. Dr. Bernhard Rumpe
Software Engineering
RWTH Aachen University
http://www.se-rwth.de/
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Hot Spot
Page 27
 A hot spot is a place in the generated code that is planned for
adaptation by handwritten code.
 The adaptation is carried out through the generator detecting and
including appropriate HC.
 Hot spot documentation needs:
• A) How does a hot spot look like
• e.g. naming conventions for the class
• B) Signature the hot spot has to provide
• C) What is the API the hot spot can use
 The approach is similar to framework hot spots.
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Hot Spots in DEX
Page 28
 Often the GUI of a DEX product needs adaptation
• More functions, more screens, nicer appearance, …
• GUI can be customized by adding handwritten extensions
 DEX has e.g. hot spots prepared for
• Menu Extension
• Home Screen Adaptation
• Panel Extensions
• Startup and TearDown Phases
 Adapting a hot spot needs some knowledge about the mechanisms
of the adapted GUI.
 Examples of DEX SocNet adaptations:
• see DEX website: http://www.monticore.de/dex/
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Hot Spot: Menu Extension
Page 29
 Purpose: Add menu items
 Hot spot class: MainWindowViewEIMP
 Methods to override:
• extendMenu()
 Available API:
• addMenuItem(), …
public class MainWindowViewEIMP extends MainWindowView {
//constructors
public void extendMenu() {
JideMenu m = new JideMenu("StatusBar");
JMenuItem item = new JMenuItem("print");
m.add(item);
item.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
StatusBar.write("Menue item print was clicked");
}});
addMenuItem(m);
}
}
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Java
«hc»
How to Adapt the Home Screen
Page 30
 Purpose: Customize home screen
 Hot spot class: MainWindowPresenterEIMP
 Methods to override:
• setHomeTitle()
 Available API (see code):
• Swing
public class MainWindowPresenterEIMP extends MainWindowPresenter {
//constructors
public JPanel setHomeTitle() {
JPanel panel = new JPanel();
panel.setLayout(null);
JLabel lblSystem = new JLabel("SocNet System");
lblSystem.setHorizontalTextPosition(SwingConstants.CENTER);
lblSystem.setHorizontalAlignment(SwingConstants.CENTER);
lblSystem.setFont(new Font("Tahoma", Font.PLAIN, 40));
panel.setLayout(new BorderLayout(0, 0));
panel.add(lblSystem, BorderLayout.CENTER);
return panel;
}
}
Java
«hc»
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Adapting Panels
Page 31
 Purpose: Customize Panel for Specific Domain Class “X”
 Hot spot class: XEditPanelViewEIMP
 Methods to override:
• getXPanelComponent()
 Available API (see code):
• Swing
• Reusable: Methods from XEditPanelView
TagEditPanelView
Product-CD
«gen»
«interface»
ITagEditPanelView
«gen»
TagEditPanelView
«hc»
TagEditPanelViewEIMP
public class TagEditPanelViewEIMP extends TagEditPanelView {
//constructors
public ITagPanelComponentView getTagPanelComponent() {
//...
} }
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
StartUp & TearDown
Page 32
 Purpose: Add startup and teardown actions
or takeover control completely
 Hot spot class: XControllerEIMP (for model X.cd)
 Methods to override:
• startUp()
• tearDown()
 Available API (see code):
• Reusable: Methods from AbstractController
public class SocNetControllerEIMP extends SocNetController{
//constructors
protected void startUp() {
//... some startUp actions
}
protected void tearDown() {
//... some tearDown actions
}
}
Java
«hc»
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Summary – Lessons learned
Page 33
 Hot spots are HC classes that replace generated classes
• and at the same time inherit their functionality for reuse
 Hot spots can be used for various purposes:
• Signature extension
• Method overwriting
• Functionality extension
 Hot spots allow to inject HC into a generated system, thus adapting
it for specific needs
 Hot spots are filled during the generation process
• and identified through naming conventions
 Hot spots are usually model-specific
Farbe!
Generative
Software
Engineering
3. Integrating Handwritten Code
3.4. More Adaptation Mechanisms
Prof. Dr. Bernhard Rumpe
Software Engineering
RWTH Aachen University
http://www.se-rwth.de/
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Class Overriding
Page 35
 The principle:
• When X.java exists in handcoded form
 just use it and generate nothing
 Required:
• HC Java can be distinguished from GC
• e.g. disjoint directories for HC and GC
 Advantage:
• Anything can easily be adapted
 Disadvantage:
• X.java: nothing is generated anymore; no reuse
• Brittle: adaptations of model need to be tracked manually in HC
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Class Overriding plus Prototypes
Page 36
 The principle:
• When X.java exists in handcoded form
 use it, but generate XProto.java instead
• Xproto.java can be used as superclass for HC X.Java
 Advantage:
• Anything can easily be adapted
• Reuse of generated code possible, which is still there
 Disadvantage:
• Brittle: adaptations of model need to be tracked manually in HC
 Remark: very similar to the Dex approach using EIMPL
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Use GUI as Framework
Page 37
 The principle:
• The generated code may be adaptable by classic programming
techniques, e.g. usable as framework
 Required:
• Explicit hot spots (= empty methods) that can be overwritten in
subclasses
• Possibilities to adapt / configure in the generated code
 Advantage:
• Traditional form of adaptation, no interaction with generator
 Disadvantage:
• Generated code needs to be a framework
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Delegation to HC
Page 38
 The principle:
• The generated code uses delegation to hot spots
 Similar to the used inheritance approach
 Advantage:
• More flexible, e.g. individual delegators for each method
 Disadvantage:
• More complex: more objects to manage,
• Objects have substructure
Product-CD
Model-CD
Person
Person
«gen»
delegate
«gen»
«interface»
PersonDelegate
String getFullName()
String getFullName()
String getFullName()
delegator
«hc»
PersonImpl
Delegation
delegate
String getFullName()
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Partial Classes
Page 39
 The principle:
• The language allows classes to be distributed over several
artefacts, called “partial classes”
 Advantage:
• Generation of classes piecewise is possible
 Disadvantage:
• Java doesn’t support this (It can be mimicked by a design pattern)
• Generated functionality cannot be redefined
«gen»
partial class Person{
string firstName;
//…
}
Model-CD
Person
String firstName
C#
classes
have the
same names
String getFullName()
«hc»
partial class Person{
public string getFullname(){
//…
} }
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Aspect Orientation for HC-Injection
Page 40
 The principle:
• Use an Aspect-Oriented Language
• Add functionality in form of Aspects
 Disadvantage:
• From SE point of view aspects are harmful. Not recommended to
use an AOP language for coding. (Much worse than goto)
Java
public class Person { «gen»
//… generated impl
AspectJ
«hc»
public aspect PersonAspect {
pointcut pcClearMembers(Person p):
execution(* Person.
clearMembers()) && target(p);
public void
clearMembers() {
//… default impl
}
void around(Person p):
pcClearMembers (p) {
// … handwritten impl
}
}
}
p = instance
on which
method shall
be executed
Handwritten
impl. in
advice
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Embed Action Language in Model
Page 41
 The principle:
• Embed a language for method implementation within the
modelling language
 Advantage:
• We get completely rid of handcoding!
 Disadvantage:
• Large model: confusing?
• IDEs are less elaborated for such kind of programming
 Examples:
• MontiCore (DEX) provides possibilities to add methods and
method bodies, e.g. in Java and python-style
• UML has its own action language defined
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Model Refers to Actions
Page 42
 The principle:
• Add references to the implementations in the model
 Variants:
• 1) GC calls the referenced HC: like delegation
• 2) Generator weaves the referenced artefact into the GC
 Disadvantage:
• Model gets polluted
• Model contains references to artefacts that should be developed
after the model  unnecessary
• IDEs are less elaborated for such kind of programming
• For 2: Checking of syntactical correctness is deferred to the
compiler (and thus too late)
Herunterladen